aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--gcc-4.4.3/Makefile.in14
-rw-r--r--gcc-4.4.3/README.google1232
-rwxr-xr-xgcc-4.4.3/configure30
-rw-r--r--gcc-4.4.3/configure.ac22
-rw-r--r--gcc-4.4.3/gcc/ChangeLog.ix86274
-rw-r--r--gcc-4.4.3/gcc/Makefile.in76
-rw-r--r--gcc-4.4.3/gcc/attribs.c5
-rw-r--r--gcc-4.4.3/gcc/builtin-types.def4
-rw-r--r--gcc-4.4.3/gcc/builtins.def3
-rw-r--r--gcc-4.4.3/gcc/c-common.c74
-rw-r--r--gcc-4.4.3/gcc/c-cppbuiltin.c5
-rw-r--r--gcc-4.4.3/gcc/c-opts.c36
-rw-r--r--gcc-4.4.3/gcc/c.opt10
-rw-r--r--gcc-4.4.3/gcc/caller-save.c2
-rw-r--r--gcc-4.4.3/gcc/calls.c4
-rw-r--r--gcc-4.4.3/gcc/cfgexpand.c171
-rw-r--r--gcc-4.4.3/gcc/cgraph.c33
-rw-r--r--gcc-4.4.3/gcc/cgraph.h12
-rw-r--r--gcc-4.4.3/gcc/cgraphbuild.c30
-rw-r--r--gcc-4.4.3/gcc/common.opt51
-rw-r--r--gcc-4.4.3/gcc/config.gcc40
-rw-r--r--gcc-4.4.3/gcc/config.in12
-rw-r--r--gcc-4.4.3/gcc/config/arm/arm-protos.h4
-rw-r--r--gcc-4.4.3/gcc/config/arm/arm.c1197
-rw-r--r--gcc-4.4.3/gcc/config/arm/arm.h99
-rw-r--r--gcc-4.4.3/gcc/config/arm/arm.md22
-rw-r--r--gcc-4.4.3/gcc/config/arm/bpabi.h14
-rw-r--r--gcc-4.4.3/gcc/config/arm/constraints.md21
-rw-r--r--gcc-4.4.3/gcc/config/arm/linux-eabi.h1
-rw-r--r--gcc-4.4.3/gcc/config/arm/t-arm-elf7
-rw-r--r--gcc-4.4.3/gcc/config/arm/thumb2.md57
-rw-r--r--gcc-4.4.3/gcc/config/i386/atom.md796
-rw-r--r--gcc-4.4.3/gcc/config/i386/cpuid.h2
-rw-r--r--gcc-4.4.3/gcc/config/i386/cygming.h4
-rw-r--r--gcc-4.4.3/gcc/config/i386/driver-i386.c23
-rw-r--r--gcc-4.4.3/gcc/config/i386/i386-c.c9
-rw-r--r--gcc-4.4.3/gcc/config/i386/i386-protos.h8
-rw-r--r--gcc-4.4.3/gcc/config/i386/i386.c912
-rw-r--r--gcc-4.4.3/gcc/config/i386/i386.h22
-rw-r--r--gcc-4.4.3/gcc/config/i386/i386.md219
-rw-r--r--gcc-4.4.3/gcc/config/i386/i386.opt12
-rw-r--r--gcc-4.4.3/gcc/config/i386/linux-unwind.h2
-rw-r--r--gcc-4.4.3/gcc/config/i386/linux.h2
-rw-r--r--gcc-4.4.3/gcc/config/i386/linux64.h10
-rw-r--r--gcc-4.4.3/gcc/config/i386/lwpintrin.h100
-rw-r--r--gcc-4.4.3/gcc/config/i386/mingw32.h2
-rw-r--r--gcc-4.4.3/gcc/config/i386/ppro.md8
-rw-r--r--gcc-4.4.3/gcc/config/i386/sse.md62
-rw-r--r--gcc-4.4.3/gcc/config/i386/ssemath.h25
-rw-r--r--gcc-4.4.3/gcc/config/i386/x86intrin.h4
-rw-r--r--gcc-4.4.3/gcc/config/linux-android.h6
-rw-r--r--gcc-4.4.3/gcc/config/linux.h8
-rw-r--r--gcc-4.4.3/gcc/config/mips/linux64.h4
-rw-r--r--gcc-4.4.3/gcc/config/rs6000/linux64.h2
-rw-r--r--gcc-4.4.3/gcc/config/rs6000/sysv4.h7
-rw-r--r--gcc-4.4.3/gcc/config/sparc/sparc.c10
-rwxr-xr-xgcc-4.4.3/gcc/configure123
-rw-r--r--gcc-4.4.3/gcc/configure.ac65
-rw-r--r--gcc-4.4.3/gcc/coverage.c178
-rw-r--r--gcc-4.4.3/gcc/coverage.h11
-rw-r--r--gcc-4.4.3/gcc/cp/call.c81
-rw-r--r--gcc-4.4.3/gcc/cp/class.c18
-rw-r--r--gcc-4.4.3/gcc/cp/cp-lang.c8
-rw-r--r--gcc-4.4.3/gcc/cp/cp-tree.h34
-rw-r--r--gcc-4.4.3/gcc/cp/cvt.c2
-rw-r--r--gcc-4.4.3/gcc/cp/error.c47
-rw-r--r--gcc-4.4.3/gcc/cp/lang-specs.h6
-rw-r--r--gcc-4.4.3/gcc/cp/name-lookup.c21
-rw-r--r--gcc-4.4.3/gcc/cp/parser.c50
-rw-r--r--gcc-4.4.3/gcc/cp/pt.c100
-rw-r--r--gcc-4.4.3/gcc/cp/typeck2.c23
-rw-r--r--gcc-4.4.3/gcc/dbgcnt.def1
-rw-r--r--gcc-4.4.3/gcc/doc/extend.texi48
-rw-r--r--gcc-4.4.3/gcc/doc/gcov.texi10
-rw-r--r--gcc-4.4.3/gcc/doc/install.texi5
-rw-r--r--gcc-4.4.3/gcc/doc/invoke.texi204
-rw-r--r--gcc-4.4.3/gcc/doc/md.texi5
-rw-r--r--gcc-4.4.3/gcc/doc/tm.texi31
-rw-r--r--gcc-4.4.3/gcc/dwarf2out.c56
-rw-r--r--gcc-4.4.3/gcc/dyn-ipa.c379
-rw-r--r--gcc-4.4.3/gcc/esp.h145
-rw-r--r--gcc-4.4.3/gcc/explow.c4
-rw-r--r--gcc-4.4.3/gcc/expr.h2
-rw-r--r--gcc-4.4.3/gcc/final.c122
-rw-r--r--gcc-4.4.3/gcc/flags.h10
-rw-r--r--gcc-4.4.3/gcc/fold-const.c41
-rw-r--r--gcc-4.4.3/gcc/fortran/module.c2
-rw-r--r--gcc-4.4.3/gcc/function.h4
-rw-r--r--gcc-4.4.3/gcc/gcc.c41
-rw-r--r--gcc-4.4.3/gcc/gcov-dump.c51
-rw-r--r--gcc-4.4.3/gcc/gcov-io.c385
-rw-r--r--gcc-4.4.3/gcc/gcov-io.h288
-rw-r--r--gcc-4.4.3/gcc/gcov.c501
-rw-r--r--gcc-4.4.3/gcc/genautomata.c159
-rw-r--r--gcc-4.4.3/gcc/ggc-page.c6
-rw-r--r--gcc-4.4.3/gcc/ggc.h2
-rw-r--r--gcc-4.4.3/gcc/ipa-cp.c2
-rw-r--r--gcc-4.4.3/gcc/ipa-inline.c645
-rw-r--r--gcc-4.4.3/gcc/ipa-struct-reorg.c2
-rw-r--r--gcc-4.4.3/gcc/ira.c4
-rw-r--r--gcc-4.4.3/gcc/l-ipo.c4
-rw-r--r--gcc-4.4.3/gcc/langhooks-def.h2
-rw-r--r--gcc-4.4.3/gcc/langhooks.c2
-rw-r--r--gcc-4.4.3/gcc/langhooks.h7
-rw-r--r--gcc-4.4.3/gcc/libgcov.c1422
-rw-r--r--gcc-4.4.3/gcc/mversn-dispatch.c1705
-rw-r--r--gcc-4.4.3/gcc/objc/lang-specs.h10
-rw-r--r--gcc-4.4.3/gcc/objcp/lang-specs.h8
-rw-r--r--gcc-4.4.3/gcc/optabs.c3
-rw-r--r--gcc-4.4.3/gcc/opts.c62
-rw-r--r--gcc-4.4.3/gcc/params.def89
-rw-r--r--gcc-4.4.3/gcc/passes.c18
-rw-r--r--gcc-4.4.3/gcc/pmu-profile.c1553
-rw-r--r--gcc-4.4.3/gcc/postreload.c2
-rw-r--r--gcc-4.4.3/gcc/predict.c20
-rw-r--r--gcc-4.4.3/gcc/profile.c17
-rw-r--r--gcc-4.4.3/gcc/profile.h6
-rw-r--r--gcc-4.4.3/gcc/real.c49
-rw-r--r--gcc-4.4.3/gcc/real.h2
-rw-r--r--gcc-4.4.3/gcc/rtl.def6
-rw-r--r--gcc-4.4.3/gcc/rtl.h1
-rw-r--r--gcc-4.4.3/gcc/simplify-got.c15
-rw-r--r--gcc-4.4.3/gcc/target-def.h2
-rw-r--r--gcc-4.4.3/gcc/target.h8
-rw-r--r--gcc-4.4.3/gcc/targhooks.c6
-rw-r--r--gcc-4.4.3/gcc/targhooks.h1
-rw-r--r--gcc-4.4.3/gcc/testsuite/ChangeLog.ix8656
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/abi/forced.C2
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/debug/dwarf2/lineno-simple1.C13
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/debug/dwarf2/pr41063.C20
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/debug/dwarf2/pr44641.C43
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/debug/dwarf2/pr46527.C18
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/init/pr42556.C10
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/ipa/ipa-cp-1.C309
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/lookup/koenig5.C32
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/lookup/koenig6.C18
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/mversn10.C54
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/mversn10a.C37
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/mversn12.C43
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/mversn14.C26
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/mversn14a.C8
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/mversn16.C39
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/mversn8.C44
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/mversn9.C31
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/other/crash-5.C16
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/other/crash-7.C19
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/other/crash-8.C109
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/template/crash56.C4
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/template/defarg13.C19
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/template/error39.C11
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_common.h47
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-50.C22
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-51.C44
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-52.C39
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-53.C40
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-54.C35
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-55.C38
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-56.C36
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-57.C22
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-58.C32
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-59.C34
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-60.C37
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-61.C15
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-62.C18
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-65.C30
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-66.C35
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-67.C32
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-68.C34
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-69.C31
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-70.C38
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/torture/mversn11.C40
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/torture/mversn5.C28
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/torture/mversn5.h5
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/torture/mversn5a.C12
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/tree-prof/mversn13.C37
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/tree-prof/mversn15.C23
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/tree-prof/mversn15a.C26
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/uninit-pred-3_a.C77
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/uninit-pred-3_b.C87
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/warn/Wnonnull-1.C16
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/warn/Wnull-conversion-1.C2
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/warn/Wnull-conversion-2.C2
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/warn/Wself-assign-1.C4
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/warn/Wself-assign-2.C6
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/warn/Wself-assign-3.C2
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/warn/Wself-assign-4.C2
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/warn/Wself-assign-5.C38
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/warn/Wself-assign-non-pod-1.C54
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/warn/Wself-assign-non-pod-2.C31
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/warn/Wself-assign-non-pod-3.C35
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/warn/Wself-assign-non-pod-4.C48
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/warn/Wself-assign-non-pod-5.C38
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/warn/nonnull2.C14
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.old-deja/g++.ns/koenig5.C4
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.c-torture/compile/pr22379.c2
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.c-torture/compile/pr42632.c2
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.c-torture/execute/pr44575.c49
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.dg/always_inline2.c4
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.dg/always_inline3.c4
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.dg/always_inline4.c23
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.dg/autopar/reduc-1.c2
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.dg/builtin-apply2.c1
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.dg/ipa/ipa-4.c2
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.dg/mversn2.c47
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.dg/mversn3.c30
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.dg/mversn4.c29
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.dg/mversn4.h5
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.dg/mversn4a.c13
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.dg/mversn6.c29
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.dg/mversn7.c45
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.dg/nrv6.c22
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.dg/overlay1.c70
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.dg/overlay2.c18
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.dg/overlay3.c18
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.dg/overlay4.c25
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.dg/overlay5.c24
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.dg/pr43564.c16
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.dg/sibcall-1.c2
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.dg/sibcall-2.c2
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.dg/sibcall-3.c4
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.dg/sibcall-4.c4
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.dg/sibcall-6.c4
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.dg/torture/mversn1.c31
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-4.c1
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.dg/torture/stackalign/stackalign.exp1
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.dg/tree-prof/ffvpt-pro-1.c14
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.dg/tree-prof/ffvpt-pro-2.c14
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.dg/tree-prof/ffvpt-pro-3.c14
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.dg/tree-prof/ffvpt-pro-4.c13
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.dg/tree-prof/ffvpt-pro.h17
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.dg/tree-prof/inliner-1.c2
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.dg/tree-ssa/alias_bug.c61
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-25.c4
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.dg/tree-ssa/integer-addr.c29
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.dg/tree-ssa/update-threading.c2
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.dg/uninit-13.c3
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.dg/vect/costmodel/i386/i386-costmodel-vect.exp2
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/x86_64-costmodel-vect.exp2
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.dg/vect/vect.exp2
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.dg/winline-5.c2
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/arm/aapcs/aapcs.exp35
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/arm/aapcs/abitest.h122
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/arm/aapcs/vfp1.c17
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/arm/aapcs/vfp10.c38
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/arm/aapcs/vfp11.c39
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/arm/aapcs/vfp12.c38
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/arm/aapcs/vfp13.c39
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/arm/aapcs/vfp14.c24
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/arm/aapcs/vfp15.c20
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/arm/aapcs/vfp16.c22
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/arm/aapcs/vfp17.c20
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/arm/aapcs/vfp2.c19
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/arm/aapcs/vfp3.c21
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/arm/aapcs/vfp4.c20
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/arm/aapcs/vfp5.c30
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/arm/aapcs/vfp6.c30
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/arm/aapcs/vfp7.c37
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/arm/aapcs/vfp8.c37
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/arm/aapcs/vfp9.c38
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/arm/eabi1.c71
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/arm/g2.c2
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/arm/loop-autoinc.c18
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/arm/mmx-1.c2
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/arm/pr44999.c9
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/arm/pr46631.c16
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/arm/scd42-2.c2
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/arm/thumb2-cmpneg2add-1.c12
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/arm/thumb2-cmpneg2add-2.c12
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/bfin/loop-autoinc.c16
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/i386/align-main-1.c2
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/i386/align-main-2.c2
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/i386/incoming-10.c19
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/i386/incoming-11.c18
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/i386/incoming-12.c20
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/i386/incoming-13.c15
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/i386/incoming-14.c15
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/i386/incoming-15.c15
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/i386/incoming-6.c17
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/i386/incoming-7.c16
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/i386/incoming-8.c18
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/i386/incoming-9.c18
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/i386/max-stack-align.c14
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/i386/movbe-1.c18
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/i386/movbe-2.c19
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/i386/pr37843-4.c13
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/i386/sse-12.c2
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/i386/sse-13.c15
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/i386/sse-14.c17
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/i386/sse-22.c22
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/i386/sse-23.c47
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/i386/sse2-vec-2a.c4
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/x86_64/abi/callabi/func-2a.c27
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/x86_64/abi/callabi/func-2b.c13
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/x86_64/abi/callabi/func-indirect-2a.c17
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/x86_64/abi/callabi/func-indirect-2b.c24
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/x86_64/abi/callabi/vaarg-4a.c24
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/x86_64/abi/callabi/vaarg-4b.c31
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/x86_64/abi/callabi/vaarg-5a.c17
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/x86_64/abi/callabi/vaarg-5b.c37
-rw-r--r--gcc-4.4.3/gcc/testsuite/lib/scanasm.exp37
-rw-r--r--gcc-4.4.3/gcc/testsuite/lib/target-supports.exp26
-rw-r--r--gcc-4.4.3/gcc/timevar.def1
-rw-r--r--gcc-4.4.3/gcc/toplev.c4
-rw-r--r--gcc-4.4.3/gcc/tree-dfa.c26
-rw-r--r--gcc-4.4.3/gcc/tree-flow.h6
-rw-r--r--gcc-4.4.3/gcc/tree-inline.c6
-rw-r--r--gcc-4.4.3/gcc/tree-pass.h3
-rw-r--r--gcc-4.4.3/gcc/tree-profile.c757
-rw-r--r--gcc-4.4.3/gcc/tree-sample-profile.c184
-rw-r--r--gcc-4.4.3/gcc/tree-sample-profile.h10
-rw-r--r--gcc-4.4.3/gcc/tree-ssa-alias.c32
-rw-r--r--gcc-4.4.3/gcc/tree-ssa-dce.c55
-rw-r--r--gcc-4.4.3/gcc/tree-ssa-loop-im.c4
-rw-r--r--gcc-4.4.3/gcc/tree-ssa-loop-ivopts.c404
-rw-r--r--gcc-4.4.3/gcc/tree-ssa-lrs.c8
-rw-r--r--gcc-4.4.3/gcc/tree-ssa-operands.c14
-rw-r--r--gcc-4.4.3/gcc/tree-ssa-pre.c1
-rw-r--r--gcc-4.4.3/gcc/tree-ssa-sccvn.c30
-rw-r--r--gcc-4.4.3/gcc/tree-ssa-uninit.c219
-rw-r--r--gcc-4.4.3/gcc/tree-ssa.c13
-rw-r--r--gcc-4.4.3/gcc/tree-stack-overlay.c1004
-rw-r--r--gcc-4.4.3/gcc/tree-stack-overlay.h27
-rw-r--r--gcc-4.4.3/gcc/tree-threadsafe-analyze.c556
-rw-r--r--gcc-4.4.3/gcc/tree-vrp.c2
-rw-r--r--gcc-4.4.3/gcc/unwind-dw2-fde-glibc.c4
-rw-r--r--gcc-4.4.3/gcc/value-prof.c709
-rw-r--r--gcc-4.4.3/gcc/value-prof.h16
-rw-r--r--gcc-4.4.3/gcc/varasm.c6
-rw-r--r--gcc-4.4.3/libgcc/Makefile.in18
-rw-r--r--gcc-4.4.3/libiberty/getpagesize.c1
-rw-r--r--gcc-4.4.3/libmudflap/Makefile.in10
-rwxr-xr-xgcc-4.4.3/libmudflap/configure48
-rw-r--r--gcc-4.4.3/libmudflap/configure.ac2
-rw-r--r--gcc-4.4.3/libstdc++-v3/include/backward/hashtable.h3
-rw-r--r--gcc-4.4.3/libstdc++-v3/include/bits/stl_algo.h7
-rw-r--r--gcc-4.4.3/libstdc++-v3/include/bits/stl_tree.h26
-rw-r--r--gcc-4.4.3/libstdc++-v3/include/ext/sso_string_base.h51
-rw-r--r--gcc-4.4.3/libstdc++-v3/include/ext/vstring.h4
-rw-r--r--gcc-4.4.3/libstdc++-v3/include/ext/vstring.tcc10
339 files changed, 21220 insertions, 2210 deletions
diff --git a/gcc-4.4.3/Makefile.in b/gcc-4.4.3/Makefile.in
index ada717f89..53a5146aa 100644
--- a/gcc-4.4.3/Makefile.in
+++ b/gcc-4.4.3/Makefile.in
@@ -305,9 +305,17 @@ WINDRES_FOR_BUILD = @WINDRES_FOR_BUILD@
BUILD_PREFIX = @BUILD_PREFIX@
BUILD_PREFIX_1 = @BUILD_PREFIX_1@
+# Some stuff don't compile with SSP
+enable_esp = @enable_esp@
+ifeq ($(enable_esp),yes)
+ESP_NOSSP_CFLAGS = -fno-stack-protector
+else
+ESP_NOSSP_CFLAGS=
+endif
+
# Flags to pass to stage2 and later makes. They are defined
# here so that they can be overridden by Makefile fragments.
-BOOT_CFLAGS= -g -O2
+BOOT_CFLAGS= -g -O2 $(ESP_NOSSP_CFLAGS)
BOOT_LDFLAGS=
BOOT_ADAFLAGS=-gnatpg -gnata
@@ -350,9 +358,9 @@ GNATMAKE = @GNATMAKE@
CFLAGS = @CFLAGS@
LDFLAGS = @LDFLAGS@
-LIBCFLAGS = $(CFLAGS)
+LIBCFLAGS = $(CFLAGS) $(ESP_NOSSP_CFLAGS)
CXXFLAGS = @CXXFLAGS@
-LIBCXXFLAGS = $(CXXFLAGS) -fno-implicit-templates
+LIBCXXFLAGS = $(CXXFLAGS) -fno-implicit-templates $(ESP_NOSSP_CFLAGS)
TFLAGS =
diff --git a/gcc-4.4.3/README.google b/gcc-4.4.3/README.google
index bfddb6db5..5c749f4ac 100644
--- a/gcc-4.4.3/README.google
+++ b/gcc-4.4.3/README.google
@@ -1501,7 +1501,7 @@ gcc/testsuite/g++.dg/debug/dwarf2/dwarf4-typedef.C
Fix problem in gcc where a local typedef in a member function could produce
an ICE in output_die. (b/2479745)
Owner: ccoutant
- Status: Not yet upstream
+ Status: Upstream in GCC 4.6 at r161217.
gcc/cp/cp-lang.c
gcc/gimple.c
@@ -2016,6 +2016,162 @@ gcc/simplify-got.c
Owner: jingyu
Status: google local
+gcc/cgraph.c
+gcc/cgraph.h
+gcc/value-prof.c
+ When deleting a cgraph_node, also remove it from the pid_map to
+ avoid accidentally using an invalid cgraph_node during value
+ profiling with stale profiles.
+ Owner: nvachhar
+ Status: not yet upstream
+
+gcc/Makefile.in
+gcc/common.opt
+gcc/coverage.c
+gcc/gcov-io.h
+gcc/libgcov.c
+gcc/params.def
+gcc/profile.c
+gcc/tree-profile.c
+gcc/value-prof.h
+ Add new FDO technique based on reuse distance measurement.
+ Not on by default in either plain, FDO or LIPO.
+ Use optional flag -fprofile-reusedist for profile generation.
+ Use optional flag -foptimize-locality for profile use.
+ There are dependencies to runtime libraries not included here.
+ Owner: rus
+ Status: Google local
+
+gcc/config/arm/arm.md
+gcc/config/arm/thumb2.md
+gcc/config/arm/constraints.md
+gcc/testsuite/lib/target-supports.exp
+gcc/testsuite/gcc.target/arm/thumb2-cmpneg2add-1.c
+gcc/testsuite/gcc.target/arm/thumb2-cmpneg2add-2.c
+ Add new peephole2 to change cmn to add for thumb2 if the immediate constant
+ is a small negative number.
+ Owner: carrot
+ Status: In GCC 4.6 at revision 161040 and part of 147812(target-supports.exp).
+
+gcc/dyn-ipa.c
+gcc/gcov-io.h
+gcc/libgcov.c
+ Implement lipo module-group sorting.
+ Owner: raksit
+ Status: not yet upstream
+
+gcc/dyn-ipa.c
+ Fix a bug in the previous submission above.
+ Owner: raksit
+ Status: not yet upstream
+
+gcc/config/arm/thumb2.md
+gcc/config/arm/constraints.md
+ Correct the thumb2_addsi_short pattern.
+ Owner: carrot
+ Status: In GCC 4.5 at revision 155054.
+
+gcc/doc/invoke.texi
+gcc/final.c
+gcc/common.opt
+gcc/params.def
+ New compiler option, -fcgraph-section, to emit call graph edge profile
+ counts in .note.callgraph.text sections. This information will allow
+ the linker to reconstruct the global call graph and do better function
+ layout. A new .note.callgraph.text section is created for each function.
+ This section lists every callee and the number of times it is called. The
+ params variable "note-cgraph-section-edge-threshold" can be used to
+ only list edges above a certain threshold.
+ Owner: tmsriram
+ Status: not yet upstream
+
+gcc/opts.c
+ Fix the way -Werror=coverage-mismatch is enabled by default so that
+ -Wno-error disables it properly.
+ Owner: nvachhar
+ Status: Not yet upstream
+
+gcc/ipa-inline.c
+ Upstream patch fixing a problem with improperly updated priorities
+ (badness) of callsites during inlining.
+ Owner: meheff
+ Status: Partial backport of GCC 4.6.0 upstream patch r158278.
+
+gcc/tree-ssa-loop-ivopts.c
+gcc/dbgcnt.def
+ Fix b2776888
+ Fix a problem in multiple exit handling
+ Owner: davidxl
+ Status: the second part will be in upstream (approved)
+ The first part is in a the sinking support which is not
+ accepted upstream
+
+gcc/config/arm/arm.c
+gcc/doc/tm.texi
+gcc/simplify-got.c
+gcc/target.h
+gcc/passes.c
+ Move the simplify-got pass after loop optimization.
+ Owner: carrot
+ Status: not yet upsteam.
+
+gcc/value-prof.c
+ Make check_ic_target more robust by checking for record size if an
+ indirect call site returns a record type and also check to ensure
+ the call site and target function have a matching number of
+ parameters.
+ Owner: nvachhar
+ Status: Not yet upstream.
+
+gcc/ipa-inline.c
+ Change detailed dump of inliner to more readable tree-based format.
+ Owner: meheff
+ Status: not yet upsteam.
+
+gcc/c-opts.c
+gcc/c.opt
+gcc/cp/call.c
+gcc/cp/cvt.c
+gcc/doc/invoke.texi
+gcc/testsuite/g++.dg/warn/Wnull-conversion-1.C
+gcc/testsuite/g++.dg/warn/Wnull-conversion-2.C
+ Change the option name for null conversion warning from -Wnull-conversion
+ to -Wconversion-null to match upstream GCC's option.
+ Owner: lcwu
+ Status: not yet upstream.
+
+gcc/Makefile.in
+gcc/c-opts.c
+gcc/doc/invoke.texi
+gcc/dyn-ipa.c
+gcc/ggc-page.c
+gcc/ggc.h
+gcc/params.def
+ Implement memory consumption based auto-cutoff of the number of
+ imported modules during profile-use.
+ Owner: raksit
+gcc/final.c
+ Enhance assembly debug dump to include control flow annotations.
+ Owner: davidxl
+ Status: not yet upstream
+
+gcc/config/arm/thumb2.md
+ Replace tst instruction with lsls for a single bit test.
+ Owner: carrot
+ Status: back port of upstream GCC 4.6.0 patches 161344, 161929, 161930.
+
+gcc/ipa-inline.c
+ Properly update all callsite priorities after each inlining decision.
+ Owner: meheff
+ Status: not yet upsteam.
+
+gcc/params.def
+ Lower the lipo maximum memory limit so that a couple of benchmarks that
+ did't build earlier on the compiler-team forge cluster (which apparently
+ has lower memory limits than public forge cluster) can build now.
+ Owner: raksit
+ Status: not yet upstream
+
config.sub
gcc/config.gcc
gcc/config/linux.h
@@ -2061,21 +2217,405 @@ gcc/config/arm/thumb2.md
Owner: jingyu
Status: Back port upstream patch r157942
+gcc/ipa-inline.c
+ Change inlining heuristic in a few ways:
+ (1) Change base priority to average growth per callsite.
+ (2) Clean out some crufty elements of priority formula.
+ (3) Add threshold parameter which enables inlining of high priority
+ callsites of functions not marked inline.
+ Owner: meheff
+ Status: not yet upsteam.
+
gcc/config/arm/arm.h
Add .note.GNU-stack annotation to all ARM targeted codes.
Owner: jingyu
Status: keep it local
-gcc/config/arm/thumb2.md
- Replace tst instruction with lsls for a single bit test.
+gcc/cp/pt.c
+gcc/testsuite/lib/scanasm.exp
+gcc/testsuite/g++.dg/debug/dwarf2/lineno-simple1.C
+gcc/testsuite/g++.dg/debug/dwarf2/pr44641.C
+ Fix debug locations of certain template instantiations
+ Owner: jyasskin
+ Status: backport of upstream r162349 and r162383, and a very small
+ piece of 147866.
+
+gcc/calls.c
+gcc/fortran/module.c
+gcc/ipa-struct-reorg.c
+ Fix spurious "may be used uninitialized" errors. This is required to
+ compile gcc with optimization enabled.
+ Owner: aaw
+ Status: google-local
+
+gcc/tree-ssa-uninit.c
+ Fix 2862386
+ Owner: davidxl
+ Status: not yet upstream
+
+gcc/cp/typeck2.c
+gcc/testsuite/g++.dg/init/pr42556.C
+ Drop empty CONSTRUCTOR when all of its elements are explicitly initialized.
Owner: carrot
- Status: back port of upstream GCC 4.6.0 patches 161344, 161929, 161930.
+ Status: Back port from upstream patch r158047.
+
+libstdc++-v3/include/bits/stl_algo.h
+libstdc++-v3/include/bits/stl_tree.h
+ For http://b/1731200, make sure that debug checks do not hide compilation
+ errors.
+ Owner: ppluzhnikov
+ Status: google-local
+
+gcc/c.opt
+gcc/doc/extend.texi
+gcc/doc/invoke.texi
+gcc/testsuite/g++.dg/warn/Wnonnull-1.C
+ Enable -Wnonnull check in C++.
+ Owner: lcwu
+ Status: not yet upstream
+
+gcc/caller-save.c
+gcc/ira.c
+gcc/postreload.c
+gcc/rtl.h
+ Fix long build time for MaoDefs.cc. b/2524357.
+ http://gcc.gnu.org/ml/gcc-cvs/2010-08/msg00135.html
+ Owner: martint
+ Status: in gcc 4.5
libiberty/getpagesize.c
Local work around for building C++ library for Android toolchain.
Owner: jingyu
Status: keep it local
+gcc/ipa-inline.c
+gcc/params.def
+gcc/tree-ssa-lrs.c
+ Improvements to inliner size estimation heuristics. Account for linker
+ garbage collection, and function prologue/epilogue/alignment size. Changes
+ to tree-ssa-lrs.c are due to "may be used uninitialized" warnings exposed by
+ the inlining heuristic changes.
+ Owner: meheff
+ Status: not yet upstream
+
+gcc/config/arm/arm.md
+gcc/config/arm/thumb2.md
+gcc/testsuite/gcc.target/arm/pr44999.c
+ Change "and r0, r0, 255" to uxtb in thumb2.
+ Owner: carrot
+ Status: back port from upstream GCC 4.6 patch r163184.
+
+gcc/cp/name-lookup.c
+gcc/testsuite/g++.dg/lookup/koenig5.C
+gcc/testsuite/g++.dg/lookup/koenig6.C
+gcc/testsuite/g++.dg/template/crash56.C
+gcc/testsuite/g++.old-deja/g++.ns/koenig5.C
+ Ignore non-functions during argument-dependent lookup.
+ http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17365
+ http://gcc.gnu.org/viewcvs?view=revision&revision=153905
+ Owner: aaw
+ Status: backport of upstream rev. 153905
+
+gcc/tree-profile.c
+ Change prefix of -foptimize-locality runtime from __libopt__ to libopt__.
+ Owner: rus
+ Status: google-local
+
+gcc/value-prof.c
+ Disable the stringops value profile transformations when -foptimize-locality
+ is turned on.
+ Owner: rus
+ Status: google-local
+
+gcc/cp/call.c
+gcc/cp/class.c
+gcc/cp/cp-lang.c
+gcc/cp/cp-tree.h
+gcc/langhooks-def.h
+gcc/langhooks.c
+gcc/langhooks.h
+gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-50.C
+gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-51.C
+gcc/tree-threadsafe-analyze.c
+ Add support for allowing non-const but non-modifying methods to be
+ protected by reader locks.
+ Owner: lcwu
+ Status: not yet upstream
+
+gcc/c-common.c
+gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-52.C
+gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-53.C
+gcc/tree-threadsafe-analyze.c
+ Added support to allow point_to_guarded_by and point_to_guarded attributes
+ on smart/scoped pointers.
+ Owner: lcwu
+ Status: not yet upstream
+
+gcc/tree-profile.c
+ Calls to builtin functions must not be instrumented by the direct call
+ profiler. Check for DECL_BUILT_IN, in addition to the already present
+ DECL_IS_BUILTIN check.
+ Owner: raksit
+ Status: not yet upstream
+
+gcc/dyn-ipa.c
+ Reduce memory consumption during dynamic-call-graph-analysis of LIPO
+ profile collection run (upto 30x), by making use of hash set instead
+ of sparse array.
+ Owner: raksit
+ Status: not yet upstream
+
+gcc/params.def
+ Lower lipo profile-use maximum-memory threshold from 2.8G to 2.4G
+ Owner: raksit
+ Status: not yet upstream
+
+gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-56.C
+gcc/tree-threadsafe-analyze.c
+ Fix a bug in handling annotated member functions accessed through smart
+ pointer wrapped objects.
+ Owner: lcwu
+ Status: not yet upstream
+
+gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-57.C
+gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-58.C
+gcc/tree-threadsafe-analyze.c
+ Modify annotalysis so that a variable passed into a function for a
+ reference parameter is consider a use of this variable.
+ Owner: lcwu
+ Status: not yet upstream
+
+gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-54.C
+gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-55.C
+gcc/tree-threadsafe-analyze.c
+ Fix a bug in annotalysis' handling of the annotations that specify function
+ parameters as its lock arguments. We should not prepend the base object in
+ such cases.
+ Owner: lcwu
+ Status: not yet upstream
+
+libstdc++-v3/include/ext/sso_string_base.h
+libstdc++-v3/include/ext/vstring.h
+libstdc++-v3/include/ext/vstring.tcc
+ Remove unqualified lookups into dependent template base classes from STL
+ headers. These break clang. See http://b/2961693.
+ Owner: aaw
+ Status: not yet upstream
+
+gcc/cp/cp-tree.h
+gcc/cp/error.c
+gcc/cp/pt.c
+gcc/testsuite/g++.dg/template/defarg13.C
+gcc/testsuite/g++.dg/template/error39.C
+ Elide default arguments when printing templates in error messages.
+ http://b/2904171
+ Owner: aaw
+ Status: backport of uptream revisions 145566, 150223, and 149066.
+
+gcc/attribs.c
+gcc/c-common.c
+gcc/c-cppbuiltin.c
+gcc/testsuite/g++.dg/thread-ann/thread_annot_common.h
+gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-59.C
+gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-60.C
+gcc/tree-threadsafe-analyze.c
+ Add additional lock annotations/attributes to support (finer-grain)
+ escape hatches and allow annotalysis to understand some of tsan's dynamic
+ annotations.
+ Owner: lcwu
+ Status: not yet upstream
+
+gcc/gcc-4.4.3/libstdc++-v3/include/backward/hashtable.h
+ Intialize member fields of Hashtable_iterator in default constructor.
+ Owner: davidxl
+ Status: not yet upstream
+
+gcc/cp/cp-lang.c
+gcc/cp/cp-tree.h
+gcc/cp/error.c
+gcc/cp/parser.c
+gcc/cp/pt.c
+gcc/testsuite/g++.dg/other/crash-5.C
+gcc/testsuite/g++.dg/other/crash-7.C
+gcc/testsuite/g++.dg/other/crash-8.C
+ Don't elide default arguments for template names in debug info. Also,
+ simplify the implementation relative to http://cl/43521-p2 by storing
+ non-default argument counts during template construction. This reduces the
+ likelihood of undesired side-effects.
+ http://b/2987780
+ Owner: aaw
+ Status: backport of upstream revisions 148073 and 156351 (sans crash-6.C
+ which fails in unrelated code).
+
+gcc/config/arm/arm.c
+ Set inlining parameters to ARM-specific values.
+ Owner: meheff
+ Status: not yet upstream
+
+gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-61.C
+gcc/tree-threadsafe-analyze.c
+ Fix a bug in the handling of checking variables passed to a function by
+ reference. When the argument is an SSA name, we should simply grab the RHS of
+ its SSA DEF instead of calling get_canonical_lock_expr which does more than
+ what we need and would introduce infinite mutual-recursion in some cases.
+ Owner: lcwu
+ Status: not yet upstream
+
+gcc/l-ipo.c
+gcc/common.opt
+gcc/doc/invoke.texi
+ Add option -fripa-no-promote-always-inline-func
+ Owner: davidxl
+ Status: not yet upstream
+
+gcc/i386/i386.c
+gcc/testsuite/gcc.c-torture/execute/pr44575.c
+ When copying va_arg from a set of register save slots into a temporary, if
+ the container is bigger than type size, do the copying using smaller mode or
+ using memcpy.
+ Owner: eraman
+ Status: backport of upstream revision 161097
+
+gcc/cp/call.c
+gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-62.C
+ Fix an issue in the support that allows non-const but non-modifying methods
+ to be protected by reader locks (cl/43309-p2). The previous fix only handles
+ methods but not overloaded operators (e.g. operator[]).
+ Owner: lcwu
+
+gcc/l-ipo.c
+ fix bug in option -fripa-no-promote-always-inline-func
+ Owner: davidxl
+ Status: not yet upstream
+
+gcc/ipa-inline.c
+ Fix problem where inconsistent profile caused a divide by zero error
+ in the compiler
+ Owner: rlevin
+ Status: not yet upstream
+
+gcc/tree-ssa-alias.c
+gcc/tree-ssa-operands.c
+gcc/tree-ssa-loop-im.c
+gcc/testsuite/gcc.dg/tree-ssa/indirect-addr.c
+ Fix b/3034345: incorrect code generation with integer address
+ Owner: davidxl
+ Status: not yet stream (not needed)
+
+gcc/tree-inline.c
+ Fix b3052769
+ Owner: davidxl
+ Status: not yet upstream
+
+gcc/opts.c
+gcc/toplev.c
+gcc/testsuite/gcc.dg/pr43564.c
+gcc/testsuite/gcc.dg/nrv6.c
+ Fix b/3065307: internal compiler error in tree_nrv
+ Owner: eraman
+ Status: Upstream r157795. nrv6.c is a local test case.
+
+gcc/ChangeLog.ix86
+gcc/doc/md.texi
+gcc/genautomata.c
+gcc/rtl.def
+ Added bypass choice.
+ http://gcc.gnu.org/viewcvs?view=revision&revision=145155
+ Owner: asharif
+ Status: Upstream in ix86 branch r145155. Also in trunk.
+
+gcc/config.gcc
+gcc/config/i386/cpuid.h
+gcc/config/i386/i386-c.c
+gcc/config/i386/i386.c
+gcc/config/i386/i386.h
+gcc/config/i386/i386.md
+gcc/config/i386/i386.opt
+gcc/config/i386/lwpintrin.h
+gcc/config/i386/x86intrin.h
+gcc/doc/extend.texi
+gcc/doc/invoke.texi
+gcc/testsuite/gcc.target/i386/sse-12.c
+gcc/testsuite/gcc.target/i386/sse-13.c
+gcc/testsuite/gcc.target/i386/sse-14.c
+gcc/testsuite/gcc.target/i386/sse-22.c
+gcc/testsuite/gcc.target/i386/sse-23.c
+ Add support for LWP instructions of bulldozer microarchitecture.
+ Owner: eraman
+ Status: In upstream r153917 and r155217. Some local changes since patches
+ couldn't be cleanly applied.
+
+gcc/ChangeLog.ix86
+gcc/config/i386/cygming.h
+gcc/config/i386/i386-protos.h
+gcc/config/i386/i386.c
+gcc/config/i386/i386.h
+gcc/config/i386/i386.md
+gcc/config/i386/i386.opt
+gcc/config/i386/mingw32.h
+gcc/doc/invoke.texi
+gcc/testsuite/ChangeLog.ix86
+gcc/testsuite/gcc.target/x86_64/abi/callabi/func-2a.c
+gcc/testsuite/gcc.target/x86_64/abi/callabi/func-2b.c
+gcc/testsuite/gcc.target/x86_64/abi/callabi/func-indirect-2a.c
+gcc/testsuite/gcc.target/x86_64/abi/callabi/func-indirect-2b.c
+gcc/testsuite/gcc.target/x86_64/abi/callabi/vaarg-4a.c
+gcc/testsuite/gcc.target/x86_64/abi/callabi/vaarg-4b.c
+gcc/testsuite/gcc.target/x86_64/abi/callabi/vaarg-5a.c
+gcc/testsuite/gcc.target/x86_64/abi/callabi/vaarg-5b.c
+ Replace DEFAULT_ABI with ix86_abi. Add some tests that were upstream.
+ http://gcc.gnu.org/viewcvs?view=revision&revision=145157
+ Owner: asharif
+ Status: Upstream in ix86 branch r145157. Also in trunk.
+
+gcc/ChangeLog.ix86
+gcc/config/i386/i386-protos.h
+gcc/config/i386/i386.c
+ Rewrite of ix86_agi_dependent() function.
+ http://gcc.gnu.org/viewcvs?view=revision&revision=145236
+ Owner: asharif
+ Status: Upstream in ix86 branch r145236. Also in trunk.
+
+gcc/ChangeLog.ix86
+gcc/config/i386/i386.c
+ Move initialization of ix86_abi.
+ http://gcc.gnu.org/viewcvs?view=revision&revision=145450
+ Owner: asharif
+ Status: Upstream in ix86 branch r145450. Also in trunk.
+
+gcc/params.def
+ Change stack frame growth parameter to zero. With this change, the
+ stack frame growth is strictly limited during inlining by the
+ parameter large-stack-frame, which is set to 16K.
+ Owner: meheff
+ Status: Local patch
+
+gcc/testsuite/g++.dg/torture/pr45709-2.C
+gcc/testsuite/g++.dg/torture/pr45709.C
+gcc/tree-inline.c
+ Backport r164399 from upstream gcc-4_4-branch (b/3068369).
+ Owner: raksit
+ Status: In upstream branches 4.3 and onwards.
+
+gcc/Makefile.in
+ Backport fix for PR/40249. The bug causes unwanted inlining when
+ compiling crtstuff.c for PowerPC platforms. Symptom is segv on
+ program exit, due to register corruption caused by invalid _fini
+ function in crtbeginT.o.
+ * Makefile.in (CRTSTUFF_CFLAGS): Replace -fno-inline-functions
+ with -fno-inline.
+ http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40249
+ http://gcc.gnu.org/viewcvs?view=revision&revision=147907
+ Owner: simonb
+ Status: Backport upstream branch 4.5 r147907.
+
+gcc/params.def
+ Change stack frame growth parameter to zero. With this change, the
+ stack frame growth is strictly limited during inlining by the
+ parameter large-stack-frame, which is set to 16K.
+ Owner: meheff
+ Status: Local patch
+
gcc/testsuite/g++.dg/torture/pr45709-2.C
gcc/testsuite/g++.dg/torture/pr45709.C
gcc/tree-inline.c
@@ -2083,11 +2623,401 @@ gcc/tree-inline.c
Owner: raksit
Status: In upstream branches 4.3 and onwards.
+gcc/Makefile.in
+ Backport fix for PR/40249. The bug causes unwanted inlining when
+ compiling crtstuff.c for PowerPC platforms. Symptom is segv on
+ program exit, due to register corruption caused by invalid _fini
+ function in crtbeginT.o.
+ * Makefile.in (CRTSTUFF_CFLAGS): Replace -fno-inline-functions
+ with -fno-inline.
+ http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40249
+ http://gcc.gnu.org/viewcvs?view=revision&revision=147907
+ Owner: simonb
+ Status: Backport upstream branch 4.5 r147907.
+
+gcc/cp/call.c
+gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-65.C
+ Fix a bug in cl/43309-p2 that allows non-const but non-modifying
+ overload methods to be protected by reader locks. In the original
+ implementation, when iterating through all possible overload
+ candidate functions, we didn't consider the fact that if a candidate
+ is a builtin, cand->fn actually contains an identifier node instead
+ of a function decl node. The bug caused the compiler to seg-fault.
+ Owner: lcwu
+ Status: Not yet upstream
+
+gcc/tree-inline.c
+ Improve error message when failing to inline an always_inline function.
+ Owner: meheff
+ Status: Not yet upstream
+
+gcc/testsuite/gcc.dg/always_inline2.c
+gcc/testsuite/gcc.dg/always_inline3.c
+ Fix testsuite failures due to change in inlining failure error message
+ for always_inline functions.
+ Owner: meheff
+ Status: Not yet upstream
+
+gcc/ipa-inline.c
+gcc/params.def
+ Unify inlining priority as growth/frequency and add priority tie-breakers
+ to stabilize inlining decisions in the presence of incosequential
+ code changes.
+ Owner: meheff
+
+gcc/ipa-inline.c
+ Add missing semicolon to fix compilation error.
+ Owner: meheff
+ Status: Local patch
+
+gcc/tree-ssa-uninit.C
+gcc/testsuite/g++.db/uninit-pred-3_a.C
+gcc/testsuite/g++.db/uninit-pred-3_b.C
+ Uninitialized variable warning enhancement
+ Owner: davidxl
+ Status: in upstream 4.6
+
+libstdc++-v3/include/ext/sso_string_base.h
+ Use different macro to guard scribbling on dangling strings, so
+ string::operator[] fixit can be run separately from dangling
+ string fixit.
+ Owner: ppluzhnikov
+ Status: google-local patch
+
+gcc/tree-ssa.c
+gcc/tree-ssa-uninit.c
+gcc/tree-flow.h
+gcc/c-opts.c
+gcc/opts.c
+gcc/common.opt
+gcc/doc/invoke.texi
+ Implement -Wmaybe-uninitialized option to control may be uninitialized warning
+ Owner: davidxl
+ Status: Not yet upstream
+
+gcc/ChangeLog.ix86
+gcc/config.gcc
+gcc/config/i386/atom.md
+gcc/config/i386/i386-c.c
+gcc/config/i386/i386.c
+gcc/config/i386/i386.h
+gcc/config/i386/i386.md
+gcc/config/i386/sse.md
+ Add atom pipeline model, tuning and insn selection.
+ Owner: asharif
+ Status: Upstream in ix86 branch r145450, r145632. Also in trunk.
+
+gcc/value-prof.c
+ Disable the stringops value profile transformations when either
+ -fprofile-reusedist or -foptimize-locality is turned on.
+ Owner: rus
+ Status: google-local
+
+gcc/opts.c
+ Fix a bug in handling -Wmaybe-uninitialized
+ Owner: davidxl
+ Status: not yet upstream
+
+gcc/ipa-inline.c
+ Fix ARM build failures by eliminating use of sqrt in inlining priority
+ compression scheme and renaming a parameter.
+ Owner: meheff
+ Status: Local patch
+
+gcc/tree-ssa-operands.c
+ Fix b/3125704
+ Owner: davidxl
+ Status: not needed in upstream
+
+gcc/testsuite/gcc.dg/tree-ssa/alias_bug.c
+ Add new test case
+ Owner: davidxl
+ Status: local patch
+
+gcc/ipa-cp.c
+ Fix segfault in updating of jump functions of functions cloned during
+ interprocedural constant propagation.
+ Owner: meheff
+ Status: not needed upstream
+
+gcc/ipa-inline.c
+ Prevent inlining which results in recursive calls to functions marked
+ always_inline.
+ Owner: meheff
+ Status: not yet upstream
+
+gcc/config/i386/i386.c:
+ Change switch cases to 'if then else' to prevent 'duplicate case value' error
+ for 32 bit builds.
+ Owner: eraman
+ Status: In upstream at r155237.
+
+gcc/config/mips/linux64.h
+ Back port 4.6 patch to add Android linker to mips.
+ Owner: jingyu
+ Status: In upstream at r160824.
+
+gcc/ChangeLog.ix86
+gcc/config/i386/atom.md
+gcc/config/i386/i386-protos.h
+gcc/config/i386/i386.c
+gcc/config/i386/i386.md
+gcc/doc/invoke.texi
+ Added atom documentation. Also changed i386.md to prefer add over lea,
+ whenever possible for Atom target.
+ Owner: asharif
+ Status: In ix86 branch in r145727 and r146444. Also in trunk.
+
+gcc/cp/parser.c
+gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-66.C
+gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-67.C
+ Fix a bug that occurs when annotating a member function definition outside
+ the class with locks that are also members in the class. The compiler
+ couldn't bind the lock names when parsing the attributes and therefore
+ emitted bogus warnings. This fix tries to re-bind the lock names again after
+ the class context is in scope.
+ Owner: lcwu
+ Status: not yet upstream
+
+gcc/testsuite/g++.dg/ipa/ipa-cp-1.C
+ Add new test case
+ Owner: meheff
+ Status: not needed upstream
+
+gcc/ChangeLog.ix86
+gcc/config/i386/driver-i386.c
+ Check extended family and model for Intel processors. Support Intel Atom.
+ Owner: asharif
+ Status: In ix86 branch in r147737 and r166085. Also in trunk.
+
+gcc/config.gcc
+gcc/config/linux.h
+gcc/config/linux-android.h
+gcc/config/arm/linux-eabi.h
+ Back port 4.6 Android related patch to fix several uclinux target.
+ Owner: jingyu
+ Status: In upstream at r162315.
+
+gcc/config/i386/linux-unwind.h
+ Back port 4.6 Bionic patch to fix i386 build with Bionic.
+ Owner: jingyu
+ Status: In upstream at r163933.
+
+
+gcc/cp/pt.c
+gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-68.C
+gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-69.C
+ Fix a bug in our delayed name binding with nested template instantiation
+ by pushing into and pop out of a stack the names that require delay binding
+ when we start and finish a template instantiation.
+ Owner: lcwu
+
+gcc/unwind-dw2-fde-glibc.c
+ Back port upstream 4.6 patch to fix x86 Bionic build.
+ Owner: jingyu
+ Status: In upstream at 163970.
+
+gcc/ChangeLog.ix86
+gcc/config/i386/cpuid.h
+gcc/config/i386/i386.c
+gcc/config/i386/i386.h
+gcc/config/i386/i386.md
+gcc/config/i386/i386.opt
+gcc/doc/invoke.texi
+gcc/testsuite/ChangeLog.ix86
+gcc/testsuite/gcc.target/i386/movbe-1.c
+gcc/testsuite/gcc.target/i386/movbe-2.c
+gcc/config/i386/driver-i386.c
+ Added PTA_MOVBE to atom.
+ Status: In ix86 branch in r147774 and r149232. Also in trunk.
+ Owner: asharif
+
+gcc/config/i386/i386.c
+gcc/config/i386/i386.h
+gcc/testsuite/gcc.target/i386/incoming-10.c
+gcc/testsuite/gcc.target/i386/incoming-11.c
+gcc/testsuite/gcc.target/i386/incoming-12.c
+gcc/testsuite/gcc.target/i386/incoming-13.c
+gcc/testsuite/gcc.target/i386/incoming-14.c
+gcc/testsuite/gcc.target/i386/incoming-15.c
+gcc/testsuite/gcc.target/i386/incoming-6.c
+gcc/testsuite/gcc.target/i386/incoming-7.c
+gcc/testsuite/gcc.target/i386/incoming-8.c
+gcc/testsuite/gcc.target/i386/incoming-9.c
+gcc/testsuite/gcc.target/i386/pr37843-4.c
+ Changed stack boundary code. It may change stack alignment.
+ Added new tests.
+ http://gcc.gnu.org/viewcvs?view=revision&revision=153780
+ Status: In ix86 branch in r153780. Also in trunk.
+ Owner: asharif
+
+gcc/tree-dfa.c
+gcc/tree-flow.h
+gcc/tree-ssa-loop-ivopts.c
+gcc/testsuite/gcc.target/bfin/loop-autoinc.c
+ Enhancement of auto increment.
+ Owner: carrot
+ Status: back port from upstream GCC 4.5 r150588.
+
+gcc/common.opt
+gcc/doc/invoke.texi
+gcc/gcov-io.h
+gcc/libgcov.c
+gcc/params.def
+gcc/profile.c
+gcc/profile.h
+gcc/tree-profile.c
+ Add sampling to branch profiling with -fprofile-generate-sampling.
+ Owner: rus
+ Status: not yet upstream
+
+gcc/ChangeLog.ix86
+gcc/config/i386/atom.md
+gcc/config/i386/i386.md
+gcc/config/i386/ppro.md
+gcc/config/i386/sse.md
+gcc/testsuite/ChangeLog.ix86
+gcc/testsuite/gcc.target/i386/sse2-vec-2a.c
+gcc/config/i386/i386.c
+ Turn on X86_TUNE_INTER_UNIT_MOVES for m_ATOM.
+ Properly handle psrldq for march=atom.
+ http://gcc.gnu.org/viewcvs?view=revision&revision=156958
+ http://gcc.gnu.org/viewcvs?view=revision&revision=161214
+ Owner: asharif
+ Status: In ix86 branch in r156958 and r161214. Also in trunk.
+
+gcc/Makefile.in
+gcc/cfgexpand.c
+gcc/common.opt
+gcc/function.h
+gcc/opts.c
+gcc/passes.c
+gcc/testsuite/gcc.dg/overlay1.c
+gcc/testsuite/gcc.dg/overlay2.c
+gcc/testsuite/gcc.dg/overlay3.c
+gcc/testsuite/gcc.dg/overlay4.c
+gcc/toplev.c
+gcc/tree-pass.h
+gcc/tree-stack-overlay.c
+gcc/tree-stack-overlay.h
+ Add support for an early stack allocation guarded by
+ -fearly-stack-alloc flag.
+ Owner: eraman
+ Status: Not yet upstream.
+
+gcc/testsuite/gcc.target/arm/loop-autoinc.c
+ Add an arm test case for the auto increment patch.
+ Owner: carrot
+ Status: Google-local patch.
+
+gcc/ChangeLog.ix86
+gcc/config.gcc
+gcc/config/i386/ssemath.h
+gcc/doc/install.texi
+gcc/testsuite/ChangeLog.ix86
+gcc/testsuite/gcc.dg/torture/stackalign/stackalign.exp
+ Support --with-fpmath=sse for x86. This fixes: b/2070963.
+ http://gcc.gnu.org/viewcvs?view=revision&revision=163239
+ Owner: asharif
+ Status: In ix86 branch in r163239. Also in trunk.
+
+gcc/common.opt
+gcc/coverage.c
+gcc/coverage.h
+gcc/doc/invoke.texi
+gcc/gcc.c
+gcc/gcov-dump.c
+gcc/gcov-io.c
+gcc/gcov-io.h
+gcc/libgcov.c
+gcc/opts.c
+gcc/params.def
+gcc/pmu-profile.c
+gcc/tree-profile.c
+libgcc/Makefile.in
+ Add FDO support for collecting PMU profiles via -fpmu-profile-generate flag.
+ Owner: singhai
+ Status: Local patch
+
+gcc/Makefile.in
+gcc/configure.ac
+gcc/configure
+gcc/gcc.c
+ For http://b/2739909, pass appropriate rpath to linker by default.
+ Owner: ppluzhnikov
+ Status: Google-local patch.
+
+gcc/pmu-profile.c
+ For http://b/3203856, guard x86 specific code with #ifdef's in order
+ to fix a broken ARM build.
+ Owner: singhai
+ Status: google-local patch
+
+gcc/c-common.c
+gcc/testsuite/g++.dg/warn/nonnull2.C
+ Add support to check whether a nonnull attribute references 'this' pointer.
+ Owner: lcwu
+ Status: not yet upstream.
+
+gcc/tree-sample-profile.c
+gcc/tree-sample-profile.h
+gcc/coverage.h
+gcc/predict.c
+gcc/value-prof.c
+gcc/cgraphbuild.c
+ SampleFDO enhancement
+ Owner: dehao
+ Status: google-local patch
+
+
+gcc/tree-flow.h
+gcc/tree-ssa-dce.c
+gcc/tree-ssa-sccvn.c
+gcc/tree-ssa-pre.c
+ Fix b/3212290
+ Owner: davidxl
+ Status: not needed in upstream
+
gcc/config/arm/cortex-a9.md
Cortex A9 machine description enhancement.
Owner: carrot
Status: back ported from upstream GCC 4.5 r153779.
+gcc/cp/pt.c
+ Fix b/3199268 / PR46527: give templates more accurate source location.
+ Owner: jyasskin
+ Status: backported from upstream GCC r167104
+
+libstdc++-v3/include/bits/stl_algo.h
+ For http://b/3243119, const-correct operator().
+ Owner: ppluzhnikov
+ Status: google-local patch.
+
+gcc/dyn-ipa.c
+ Print function name in dynanic callgraph dump
+ Owner: davidxl
+ Status: to be in upstream
+
+libstdc++-v3/include/ext/sso_string_base.h
+ For http://b/3186945, apply upstream revision
+ http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=167528
+ to eliminate overlapping memcpy() on swap with self.
+ Owner: ppluzhnikov
+ Status: upstream change 167528
+
+gcc/cfgexpand.c:
+ Guard a early stack allocation specific change with flag_early_stack_alloc.
+ Owner: eraman
+ Status: not in upstream
+
+gcc/ipa-inline.c
+gcc/testsuite/gcc.dg/always_inline4.c
+ Prevent inlining which causes the impossible to resolve situation of
+ a cycle of always_inline functions in the call graph. This generalizes
+ cl/44847. See http://b/2969299.
+ Owner: meheff
+ Status: not yet upstream
+
gcc/config/arm/arm.md
Fix bug 3264814, which was caused by missing dependencies of a previous back
port.
@@ -2112,9 +3042,303 @@ gcc/testsuite/g++.dg/init/ref15.C
Owner: dougkwan
Status: in upstream.
+gcc/Makefile.in
+gcc/builtin-types.def
+gcc/builtins.def
+gcc/c-common.c
+gcc/common.opt
+gcc/mversn-dispatch.c
+gcc/passes.c
+gcc/timevar.def
+gcc/tree-pass.h
+gcc/cgraph.c
+gcc/cgraph.h
+gcc/ipa-inline.c
+gcc/testsuite/gcc.dg/torture/mversn1.c
+gcc/testsuite/gcc.dg/mversn2.c
+gcc/testsuite/gcc.dg/mversn3.c
+gcc/testsuite/gcc.dg/mversn4.c
+gcc/testsuite/gcc.dg/mversn4a.c
+gcc/testsuite/gcc.dg/mversn4.h
+gcc/testsuite/gcc.dg/mversn6.c
+gcc/testsuite/g++.dg/torture/mversn5.C
+gcc/testsuite/g++.dg/torture/mversn5a.C
+gcc/testsuite/g++.dg/torture/mversn5.h
+gcc/testsuite/gcc.dg/mversn7.c
+gcc/testsuite/g++.dg/mversn8.C
+gcc/testsuite/g++.dg/mversn9.C
+gcc/testsuite/g++.dg/mversn10.C
+gcc/testsuite/g++.dg/mversn10a.C
+gcc/testsuite/g++.dg/torture/mversn11.C
+gcc/testsuite/g++.dg/mversn12.C
+gcc/testsuite/g++.dg/tree-prof/mversn13.C
+gcc/testsuite/g++.dg/mversn14.C
+gcc/testsuite/g++.dg/mversn14a.C
+gcc/testsuite/g++.dg/tree-prof/mversn15.C
+gcc/testsuite/g++.dg/tree-prof/mversn15a.C
+
+ Add new function attribute "version_selector".
+ Functions are marked with attribute "version_selector" only if
+ they are run-time constants. Example of such functions would
+ be those that test if a particular feature is available on a
+ particular architecture. Support has been added to hoist such
+ functions to a constructor so that they are executed only once
+ and the result is saved in a global which is used in place of
+ the function call.
+
+
+ Add support for __builtin_dispatch to allow multiversioning.
+ A new builtin is added that allows calling different functions
+ based on a run-time test. If the run-time test function is
+ called "featureTest" and the two different function versions
+ are "foo" and "bar" then the call :
+ __builtin_dispatch (featureTest, (void *) foo, (void *) bar)
+ calls foo is the test returns >=1 and bar if it returns 0.
+ Also, the flag -fclone-hot-version-paths is supported which
+ clones hot call-graph paths to such versioned functions to
+ enable maximum optimization along these paths. This is
+ equivalent to having fat binaries but for only the hot regions.
+
+ Owner: tmsriram
+ Status: google local
+
+gcc/testsuite/gcc.dg/overlay5.c
+gcc/tree-stack-overlay.c
+ Improve stack variable coalescing heuristic with -fearly-stack-alloc.
+ Owner: eraman
+ Status: local
+
+gcc/coverage.c
+gcc/doc/gcov.texi
+gcc/doc/invoke.texi
+gcc/gcov-dump.c
+gcc/gcov-io.c
+gcc/gcov-io.h
+gcc/gcov.c
+gcc/pmu-profile.c
+ Add support for parsing and dislaying PMU profile information
+ in gcov tool. Add support for collecting branch mispredict PMU
+ info on Intel and AMD platforms.
+ Owner: singhai
+ Status: google-local patch
+
+gcc/mversn-dispatch.c
+ Fix a bug related to the return type when lowering __builtin_dispatch.
+ Owner: tmsriram
+ Status: google local
+
+gcc/calls.c
+gcc/config/arm/arm-protos.h
+gcc/config/arm/arm.c
+gcc/config/arm/arm.h
+gcc/config/arm/bpabi.h
+gcc/config/arm/t-arm-elf
+gcc/config/sparc/sparc.c
+gcc/doc/extend.texi
+gcc/doc/invoke.texi
+gcc/doc/tm.texi
+gcc/explow.c
+gcc/expr.h
+gcc/optabs.c
+gcc/target-def.h
+gcc/target.h
+gcc/targhooks.c
+gcc/targhooks.h
+gcc/testsuite/gcc.dg/builtin-apply2.c
+gcc/testsuite/gcc.target/arm/aapcs/aapcs.exp
+gcc/testsuite/gcc.target/arm/aapcs/abitest.h
+gcc/testsuite/gcc.target/arm/aapcs/vfp1.c
+gcc/testsuite/gcc.target/arm/aapcs/vfp10.c
+gcc/testsuite/gcc.target/arm/aapcs/vfp11.c
+gcc/testsuite/gcc.target/arm/aapcs/vfp12.c
+gcc/testsuite/gcc.target/arm/aapcs/vfp13.c
+gcc/testsuite/gcc.target/arm/aapcs/vfp14.c
+gcc/testsuite/gcc.target/arm/aapcs/vfp15.c
+gcc/testsuite/gcc.target/arm/aapcs/vfp16.c
+gcc/testsuite/gcc.target/arm/aapcs/vfp17.c
+gcc/testsuite/gcc.target/arm/aapcs/vfp2.c
+gcc/testsuite/gcc.target/arm/aapcs/vfp3.c
+gcc/testsuite/gcc.target/arm/aapcs/vfp4.c
+gcc/testsuite/gcc.target/arm/aapcs/vfp5.c
+gcc/testsuite/gcc.target/arm/aapcs/vfp6.c
+gcc/testsuite/gcc.target/arm/aapcs/vfp7.c
+gcc/testsuite/gcc.target/arm/aapcs/vfp8.c
+gcc/testsuite/gcc.target/arm/aapcs/vfp9.c
+gcc/testsuite/gcc.target/arm/eabi1.c
+gcc/testsuite/gcc.target/arm/mmx-1.c
+gcc/testsuite/lib/target-supports.exp
+ New ARM floating point abi -mfloat-abi=hard.
+ Owner: carrot
+ Status: back ported from upstream GCC 4.5 patches r150525, r150527, r150528,
+r150530, r150531 and r150536.
+
+gcc/Makefile.in
+gcc/common.opt
+gcc/coverage.c
+gcc/coverage.h
+gcc/doc/invoke.texi
+gcc/flags.h
+gcc/fold-const.c
+gcc/gcov-io.c
+gcc/gcov-io.h
+gcc/libgcov.c
+gcc/opts.c
+gcc/profile.c
+gcc/real.c
+gcc/real.h
+gcc/testsuite/gcc.dg/tree-prof/ffvpt-pro-1.c
+gcc/testsuite/gcc.dg/tree-prof/ffvpt-pro-2.c
+gcc/testsuite/gcc.dg/tree-prof/ffvpt-pro-3.c
+gcc/testsuite/gcc.dg/tree-prof/ffvpt-pro-4.c
+gcc/tree-profile.c
+gcc/tree-vrp.c
+gcc/value-prof.c
+gcc/value-prof.h
+ Implement floating point value profile transformation (fvpt). This
+ pass enables profiling of math library calls and the possibility to
+ replace calls where arguments are very common with precalculated
+ results. The pass -ffvpt is off by default.
+ Owner: martint
+ Status: local
+
+gcc/testsuite/gcc.dg/tree-prof/ffvpt-pro.h
+ Add missing header file for ffvpt-tests.
+ Owner: martint
+ Status: local
+
+gcc/config/arm/arm.c
+ Back port upstream patch disable BB-reordering for ARM target.
+ http://gcc.gnu.org/viewcvs?view=revision&revision=153018
+ Owner: dougkwan
+ Status: In upstream rev 153018.
+
+gcc/testsuite/gcc.target/i386/max-stack-align.c
+ Brought in a testcase from upstream for lp64.
+ Owner: asharif
+ Status: In upstream r168011.
+
+libstdc++-v3/include/ext/sso_string_base.h
+ For http://b/3314076, wipe "logically dangling" part of the string with
+ 0xCD pattern.
+ Owner: ppluzhnikov
+ Status: google-local
+
+gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-70.C
+gcc/tree-threadsafe-analyze.c
+ Fix a bug (assertion failure) when processing calls to virtual functions that
+ are annotated with lock or unlock function attributes.
+ Owner: lcwu
+ Status: not yet upstream.
+
+gcc/config/arm/arm.c
+gcc/config/arm/thumb2.md
+ Change the instructions to clobber cc version for thumb2 if possible.
+ Owner: carrot
+ Status: In upstream gcc 4.6 r160458 and r160664.
+
+gcc/c.opt
+gcc/cp/parser.c
+gcc/doc/invoke.texi
+gcc/testsuite/g++.dg/warn/Wself-assign-1.C
+gcc/testsuite/g++.dg/warn/Wself-assign-2.C
+gcc/testsuite/g++.dg/warn/Wself-assign-3.C
+gcc/testsuite/g++.dg/warn/Wself-assign-4.C
+gcc/testsuite/g++.dg/warn/Wself-assign-5.C
+gcc/testsuite/g++.dg/warn/Wself-assign-non-pod-1.C
+gcc/testsuite/g++.dg/warn/Wself-assign-non-pod-2.C
+gcc/testsuite/g++.dg/warn/Wself-assign-non-pod-3.C
+gcc/testsuite/g++.dg/warn/Wself-assign-non-pod-4.C
+gcc/testsuite/g++.dg/warn/Wself-assign-non-pod-5.C
+ Add a new flag -Wself-assign-non-pod to control whether to warn on
+ self-assignment of non-POD variables. The flag is disabled by default.
+ Owner: lcwu
+ Status: not yet upstream
+
+gcc/value-prof.c
+ Remove use of glibc-only function strchrnul().
+ Owner: martint
+ Status: local
+
+gcc/config/arm/arm.c
+gcc/testsuite/gcc.target/arm/pr46631.c
+ Reduce thumb2 instructions <commutative_op> Rd, Rn, Rd to 16bit instructions.
+ Owner: carrot
+ Status: backported from upstream GCC 4.6 r167595.
+
libstdc++-v3/config/locale/generic/c_locale.cc
libstdc++-v3/config/locale/generic/c_locale.h
libstdc++-v3/config/locale/generic/time_members.cc
Hanlde NULL return value of setlocale(), required by bionic.
Owner: jingyu
Status: local
+
+gcc/testsuite/lib/scanasm.exp
+ Backport upstream patch r164527. to fix broken tests on ARM.
+ http://gcc.gnu.org/viewcvs?view=revision&revision=164527
+ Owner: dougkwan
+ Status: in r164527
+
+gcc/testsuite/gcc.dg/tree-prof/ffvpt-pro-4.c
+ Fix compilation error on armv7l-linux-gnueabi.
+ Owner: dougkwan
+ Status: local
+
+gcc/testsuite/gcc.dg/uninit-13.c
+ Mark test as expected failure. The test failed because of incorrect line
+ number in warning. bug 3374774
+ Owner: dougkwan
+ Status: local
+
+gcc/testsuite/gcc.dg/tree-prof/ffvpt-pro-3.c
+ Handle signed NaN in testcase.
+ Owner: martint
+ Status: local
+
+gcc/testsuite/gcc.dg/mversn7.c
+ Supply a body to featureTest function to work on ARM target where inlining
+ is not as aggressive as x86.
+ Owner: tmsriram
+ Status: google local
+
+gcc/testsuite/gcc.target/arm/g2.c
+gcc/testsuite/gcc.target/arm/scd42-2.c
+gcc/testsuite/gcc.target/arm/mmx-1.c
+ Skip these tests when compiling for Thumb because they are specific to
+ ARM mode. http://gcc.gnu.org/ml/gcc-patches/2010-10/msg00134.html
+ Owner: jingyu
+
+gcc/testsuite/g++.dg/abi/forced.C
+ Skip test if target needs status wrapper. Test does not work if wrapped.
+ Owner: dougkwan
+ Status: local
+
+gcc/testsuite/gcc.dg/mversn7.c
+ Fix test to work with ARM target where inlining is not as aggressive as x86.
+ Owner: tmsriram
+ Status: local
+
+gcc/gcc-4.4.3/gcc/coverage.c
+gcc/gcc-4.4.3/gcc/gcov-io.c
+gcc-4.4.3/gcc/gcov-io.h
+gcc-4.4.3/gcc/libgcov.c
+gcc-4.4.3/gcc/tree-profile.c
+ Add support for applying profile-gen to Linux kernel. Refactoring the code
+ that dumps profile information for better code sharing b/w user mode and
+ kernel mode.
+ Owner: xur
+ Statis: local
+
+gcc/config/i386/linux.h
+gcc/config/i386/linux64.h
+ Always pass --32 or --64 to the assembler, depending on compilation mode.
+ Enables (attempt) to boostrap 32-bit compiler on 64-bit x86 Linux.
+ (Provided by H.J. Lu.)
+ Owner: cgd
+ Status: backported from GCC 4.5 revs 152865 and 157143.
+
+gcc/dwarf2out.c
+gcc/testsuite/g++.dg/debug/dwarf2/pr41063.C
+ Revert CL 33375 (b/1906960) and apply the upstream patch.
+ http://gcc.gnu.org/ml/gcc-patches/2009-08/msg01508.html
+ Owner: ccoutant
+ Status: backported from GCC 4.5 revs 151185 and 151187.
diff --git a/gcc-4.4.3/configure b/gcc-4.4.3/configure
index c23e2664f..280492393 100755
--- a/gcc-4.4.3/configure
+++ b/gcc-4.4.3/configure
@@ -272,7 +272,7 @@ PACKAGE_STRING=
PACKAGE_BUGREPORT=
ac_unique_file="move-if-change"
-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS TOPLEVEL_CONFIGURE_ARGUMENTS build build_cpu build_vendor build_os build_noncanonical host_noncanonical target_noncanonical host host_cpu host_vendor host_os target target_cpu target_vendor target_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LN LN_S build_libsubdir build_subdir host_subdir target_subdir CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CXX CXXFLAGS ac_ct_CXX GNATBIND ac_ct_GNATBIND GNATMAKE ac_ct_GNATMAKE do_compare gmplibs gmpinc extra_mpfr_configure_flags ppllibs pplinc clooglibs clooginc stage1_languages DEBUG_PREFIX_CFLAGS_FOR_TARGET CFLAGS_FOR_TARGET CXXFLAGS_FOR_TARGET RPATH_ENVVAR GCC_SHLIB_SUBDIR tooldir build_tooldir CONFIGURE_GDB_TK GDB_TK INSTALL_GDB_TK build_configargs build_configdirs host_configargs configdirs target_configargs AR_FOR_BUILD AS_FOR_BUILD CC_FOR_BUILD CFLAGS_FOR_BUILD CXXFLAGS_FOR_BUILD CXX_FOR_BUILD DLLTOOL_FOR_BUILD GCJ_FOR_BUILD GFORTRAN_FOR_BUILD LDFLAGS_FOR_BUILD LD_FOR_BUILD NM_FOR_BUILD RANLIB_FOR_BUILD WINDMC_FOR_BUILD WINDRES_FOR_BUILD config_shell YACC BISON M4 LEX FLEX MAKEINFO EXPECT RUNTEST AR AS DLLTOOL LD LIPO NM RANLIB STRIP WINDRES WINDMC OBJCOPY OBJDUMP CC_FOR_TARGET CXX_FOR_TARGET GCC_FOR_TARGET GCJ_FOR_TARGET GFORTRAN_FOR_TARGET AR_FOR_TARGET AS_FOR_TARGET DLLTOOL_FOR_TARGET LD_FOR_TARGET LIPO_FOR_TARGET NM_FOR_TARGET OBJDUMP_FOR_TARGET RANLIB_FOR_TARGET STRIP_FOR_TARGET WINDRES_FOR_TARGET WINDMC_FOR_TARGET RAW_CXX_FOR_TARGET FLAGS_FOR_TARGET COMPILER_AS_FOR_TARGET COMPILER_LD_FOR_TARGET COMPILER_NM_FOR_TARGET MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT stage1_cflags stage1_checking stage2_werror_flag datarootdir docdir pdfdir htmldir LIBOBJS LTLIBOBJS'
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS TOPLEVEL_CONFIGURE_ARGUMENTS build build_cpu build_vendor build_os build_noncanonical host_noncanonical target_noncanonical host host_cpu host_vendor host_os target target_cpu target_vendor target_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LN LN_S build_libsubdir build_subdir host_subdir target_subdir enable_esp CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CXX CXXFLAGS ac_ct_CXX GNATBIND ac_ct_GNATBIND GNATMAKE ac_ct_GNATMAKE do_compare gmplibs gmpinc extra_mpfr_configure_flags ppllibs pplinc clooglibs clooginc stage1_languages DEBUG_PREFIX_CFLAGS_FOR_TARGET CFLAGS_FOR_TARGET CXXFLAGS_FOR_TARGET RPATH_ENVVAR GCC_SHLIB_SUBDIR tooldir build_tooldir CONFIGURE_GDB_TK GDB_TK INSTALL_GDB_TK build_configargs build_configdirs host_configargs configdirs target_configargs AR_FOR_BUILD AS_FOR_BUILD CC_FOR_BUILD CFLAGS_FOR_BUILD CXXFLAGS_FOR_BUILD CXX_FOR_BUILD DLLTOOL_FOR_BUILD GCJ_FOR_BUILD GFORTRAN_FOR_BUILD LDFLAGS_FOR_BUILD LD_FOR_BUILD NM_FOR_BUILD RANLIB_FOR_BUILD WINDMC_FOR_BUILD WINDRES_FOR_BUILD config_shell YACC BISON M4 LEX FLEX MAKEINFO EXPECT RUNTEST AR AS DLLTOOL LD LIPO NM RANLIB STRIP WINDRES WINDMC OBJCOPY OBJDUMP CC_FOR_TARGET CXX_FOR_TARGET GCC_FOR_TARGET GCJ_FOR_TARGET GFORTRAN_FOR_TARGET AR_FOR_TARGET AS_FOR_TARGET DLLTOOL_FOR_TARGET LD_FOR_TARGET LIPO_FOR_TARGET NM_FOR_TARGET OBJDUMP_FOR_TARGET RANLIB_FOR_TARGET STRIP_FOR_TARGET WINDRES_FOR_TARGET WINDMC_FOR_TARGET RAW_CXX_FOR_TARGET FLAGS_FOR_TARGET COMPILER_AS_FOR_TARGET COMPILER_LD_FOR_TARGET COMPILER_NM_FOR_TARGET MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT stage1_cflags stage1_checking stage2_werror_flag datarootdir docdir pdfdir htmldir LIBOBJS LTLIBOBJS'
ac_subst_files='serialization_dependencies host_makefile_frag target_makefile_frag alphaieee_frag ospace_frag'
ac_pwd=`pwd`
@@ -934,6 +934,11 @@ Optional Features:
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
--enable-gold use gold instead of ld
--enable-libada build libada directory
+ --enable-esp
+ Enable Stack protector, Position independent executable and
+ as default if we have suppot for it when compiling
+ and link with -z relro and -z now as default.
+ Linux targets supported i*86, x86_64, ppc*, sparc* and arm*
--enable-libssp build libssp directory
--disable-ppl-version-check disable check for PPL version
--disable-cloog-version-check disable check for CLooG version
@@ -2145,6 +2150,25 @@ if test "${ENABLE_LIBADA}" != "yes" ; then
noconfigdirs="$noconfigdirs gnattools"
fi
+# Check whether --enable-esp was given and target have the support.
+# Check whether --enable-esp or --disable-esp was given.
+if test "${enable_esp+set}" = set; then
+ enableval="$enable_esp"
+
+ case $target in
+ i?86*-*-linux* | x86_64*-*-linux* | ppc*-*-linux* | sparc*-*-linux* | arm*-*-linux*)
+ enable_esp=yes
+ ;;
+ *)
+ { { echo "$as_me:$LINENO: error: *** --enable-esp is not supported on this $target target." >&5
+echo "$as_me: error: *** --enable-esp is not supported on this $target target." >&2;}
+ { (exit 1); exit 1; }; }
+ ;;
+ esac
+
+fi;
+
+
# Check whether --enable-libssp or --disable-libssp was given.
if test "${enable_libssp+set}" = set; then
enableval="$enable_libssp"
@@ -12432,6 +12456,9 @@ case $build in
*) stage1_cflags="-g -J" ;;
esac ;;
esac
+if test x$enable_esp = xyes; then
+ stage1_cflags="$stage1_cflags -fno-stack-protector"
+fi
# This is aimed to mimic bootstrap with a non-GCC compiler to catch problems.
if test "$GCC" = yes; then
@@ -13235,6 +13262,7 @@ s,@build_libsubdir@,$build_libsubdir,;t t
s,@build_subdir@,$build_subdir,;t t
s,@host_subdir@,$host_subdir,;t t
s,@target_subdir@,$target_subdir,;t t
+s,@enable_esp@,$enable_esp,;t t
s,@CC@,$CC,;t t
s,@CFLAGS@,$CFLAGS,;t t
s,@LDFLAGS@,$LDFLAGS,;t t
diff --git a/gcc-4.4.3/configure.ac b/gcc-4.4.3/configure.ac
index 97e268f2f..40aea377e 100644
--- a/gcc-4.4.3/configure.ac
+++ b/gcc-4.4.3/configure.ac
@@ -383,6 +383,25 @@ if test "${ENABLE_LIBADA}" != "yes" ; then
noconfigdirs="$noconfigdirs gnattools"
fi
+# Check whether --enable-esp was given and target have the support.
+AC_ARG_ENABLE([esp],
+[ --enable-esp
+ Enable Stack protector, Position independent executable and
+ as default if we have suppot for it when compiling
+ and link with -z relro and -z now as default.
+ Linux targets supported i*86, x86_64, ppc*, sparc* and arm*],
+[
+ case $target in
+ i?86*-*-linux* | x86_64*-*-linux* | ppc*-*-linux* | sparc*-*-linux* | arm*-*-linux*)
+ enable_esp=yes
+ ;;
+ *)
+ AC_MSG_ERROR([*** --enable-esp is not supported on this $target target.])
+ ;;
+ esac
+])
+AC_SUBST([enable_esp])
+
AC_ARG_ENABLE(libssp,
[ --enable-libssp build libssp directory],
ENABLE_LIBSSP=$enableval,
@@ -2890,6 +2909,9 @@ case $build in
*) stage1_cflags="-g -J" ;;
esac ;;
esac
+if test x$enable_esp = xyes; then
+ stage1_cflags="$stage1_cflags -fno-stack-protector"
+fi
# This is aimed to mimic bootstrap with a non-GCC compiler to catch problems.
if test "$GCC" = yes; then
diff --git a/gcc-4.4.3/gcc/ChangeLog.ix86 b/gcc-4.4.3/gcc/ChangeLog.ix86
new file mode 100644
index 000000000..1f0288190
--- /dev/null
+++ b/gcc-4.4.3/gcc/ChangeLog.ix86
@@ -0,0 +1,274 @@
+2010-08-13 H.J. Lu <hongjiu.lu@intel.com>
+
+ Backport from mainline
+ 2010-02-26 H.J. Lu <hongjiu.lu@intel.com>
+
+ * config.gcc: Support --with-fpmath=sse for x86.
+
+ * config/i386/ssemath.h: New.
+
+ * doc/install.texi (--with-fpmath=sse): Documented.
+
+2010-06-22 H.J. Lu <hongjiu.lu@intel.com>
+
+ Backport from mainline
+ 2010-06-22 H.J. Lu <hongjiu.lu@intel.com>
+
+ * config/i386/i386.md (unit): Also check sseishft1.
+
+ 2010-06-21 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR target/44615
+ * config/i386/atom.md (atom_sseishft_2): Also check sseishft1.
+
+ * config/i386/i386.md (type): Add sseishft1
+
+ * config/i386/ppro_insn (ppro_insn): Also check sseishft1.
+ (ppro_insn_load): Likewise.
+ (ppro_insn_store): Likewise.
+ (ppro_insn_both): Likewise.
+
+ * config/i386/sse.md (*vec_extractv2di_1_rex64_avx): Replace
+ sseishft with sseishft1 for type.
+ (*vec_extractv2di_1_avx): Likewise.
+ (*vec_extractv2di_1_rex64): Replace sseishft with sseishft1 for
+ type. Remove atom_unit.
+ (*vec_extractv2di_1_sse2): Likewise.
+
+2010-02-22 H.J. Lu <hongjiu.lu@intel.com>
+
+ Backport from mainline:
+ 2010-02-22 H.J. Lu <hongjiu.lu@intel.com>
+ * config/i386/i386.c (initial_ix86_tune_features): Turn on
+ X86_TUNE_INTER_UNIT_MOVES for m_ATOM.
+
+2009-10-30 H.J. Lu <hongjiu.lu@intel.com>
+
+ Backport from mainline:
+ 2009-10-30 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR target/40838
+ * cfgexpand.c (expand_stack_alignment): Call update_stack_boundary
+ first. Move assert on stack_alignment_estimated just before
+ setting stack_realign_needed.
+ (gimple_expand_cfg): Initialize stack_alignment_estimated to 0.
+ Don't call update_stack_boundary.
+
+ * config/i386/i386.c (ix86_minimum_incoming_stack_boundary): New.
+ (verride_options): Don't check ix86_force_align_arg_pointer here.
+ (ix86_function_ok_for_sibcall): Use it.
+ (ix86_update_stack_boundary): Likewise.
+
+ * config/i386/i386.h (STACK_REALIGN_DEFAULT): Update comments.
+
+2009-05-21 H.J. Lu <hongjiu.lu@intel.com>
+
+ Backport from mainline:
+ 2009-05-21 H.J. Lu <hongjiu.lu@intel.com>
+ Uros Bizjak <ubizjak@gmail.com>
+
+ * config/i386/cpuid.h (bit_MOVBE): New.
+
+ * config/i386/driver-i386.c (host_detect_local_cpu): Check movbe.
+
+ * config/i386/i386.c (OPTION_MASK_ISA_MOVBE_SET): New.
+ (OPTION_MASK_ISA_MOVBE_UNSET): Likewise.
+ (ix86_handle_option): Handle OPT_mmovbe.
+ (ix86_target_string): Add -mmovbe.
+ (pta_flags): Add PTA_MOVBE.
+ (processor_alias_table): Add PTA_MOVBE to "atom".
+ (override_options): Handle PTA_MOVBE.
+
+ * config/i386/i386.h (TARGET_MOVBE): New.
+
+ * config/i386/i386.md (bswapsi2): Check TARGET_MOVBE.
+ (*bswapsi_movbe): New.
+ (*bswapdi_movbe): Likewise.
+ (bswapdi2): Renamed to ...
+ (*bswapdi_1): This.
+ (bswapdi2): New expander.
+
+ * config/i386/i386.opt (mmovbe): New.
+
+ * doc/invoke.texi: Document -mmovbe.
+
+2009-05-20 H.J. Lu <hongjiu.lu@intel.com>
+
+ Backport from mainline:
+ 2009-05-20 H.J. Lu <hongjiu.lu@intel.com>
+
+ * config/i386/driver-i386.c (host_detect_local_cpu): Check
+ extended family and model for Intel processors. Support Intel
+ Atom.
+
+2009-04-20 H.J. Lu <hongjiu.lu@intel.com>
+
+ Backport from mainline:
+ 2009-04-20 Joey Ye <joey.ye@intel.com>
+ Xuepeng Guo <xuepeng.guo@intel.com>
+ H.J. Lu <hongjiu.lu@intel.com>
+
+ * config/i386/atom.md: Add bypasses with ix86_dep_by_shift_count.
+
+ * config/i386/i386.c (LEA_SEARCH_THRESHOLD): New macro.
+ (IX86_LEA_PRIORITY): Likewise.
+ (distance_non_agu_define): New function.
+ (distance_agu_use): Likewise.
+ (ix86_lea_for_add_ok): Likewise.
+ (ix86_dep_by_shift_count): Likewise.
+
+ * config/i386/i386.md: Call ix86_lea_for_add_ok to decide we
+ should split for LEA.
+
+ * config/i386/i386-protos.h (ix86_lea_for_add_ok): Declare new
+ function.
+ (ix86_dep_by_shift_count): Likewise.
+
+2009-04-07 H.J. Lu <hongjiu.lu@intel.com>
+
+ Backport from mainline:
+ 2009-04-07 H.J. Lu <hongjiu.lu@intel.com>
+
+ * doc/invoke.texi: Document Atom support.
+
+2009-04-06 H.J. Lu <hongjiu.lu@intel.com>
+
+ * config/i386/i386.md: Revert 2 accidental checkins.
+
+2009-04-06 H.J. Lu <hongjiu.lu@intel.com>
+
+ Backport from mainline:
+ 2009-04-06 Joey Ye <joey.ye@intel.com>
+ Xuepeng Guo <xuepeng.guo@intel.com>
+ H.J. Lu <hongjiu.lu@intel.com>
+
+ Atom pipeline model, tuning and insn selection.
+ * config.gcc (atom): Add atom config options and target.
+
+ * config/i386/atom.md: New.
+
+ * config/i386/i386.c (atom_cost): New cost.
+ (m_ATOM): New macro flag.
+ (initial_ix86_tune_features): Set m_ATOM.
+ (x86_accumulate_outgoing_args): Likewise.
+ (x86_arch_always_fancy_math_387): Likewise.
+ (processor_target): Add Atom cost.
+ (cpu_names): Add Atom cpu name.
+ (override_options): Set Atom ISA.
+ (ix86_issue_rate): New case PROCESSOR_ATOM.
+ (ix86_adjust_cost): Likewise.
+
+ * config/i386/i386.h (TARGET_ATOM): New target macro.
+ (ix86_tune_indices): Add X86_TUNE_OPT_AGU.
+ (TARGET_OPT_AGU): New target option.
+ (target_cpu_default): Add TARGET_CPU_DEFAULT_atom.
+ (processor_type): Add PROCESSOR_ATOM.
+
+ * config/i386/i386.md (cpu): Add new value "atom".
+ (use_carry, movu): New attr.
+ (atom.md): Include atom.md.
+ (adddi3_carry_rex64): Set attr "use_carry".
+ (addqi3_carry): Likewise.
+ (addhi3_carry): Likewise.
+ (addsi3_carry): Likewise.
+ (*addsi3_carry_zext): Likewise.
+ (subdi3_carry_rex64): Likewise.
+ (subqi3_carry): Likewise.
+ (subhi3_carry): Likewise.
+ (subsi3_carry): Likewise.
+ (x86_movdicc_0_m1_rex64): Likewise.
+ (*x86_movdicc_0_m1_se): Likewise.
+ (x86_movsicc_0_m1): Likewise.
+ (*x86_movsicc_0_m1_se): Likewise.
+ (*adddi_1_rex64): Emit add insn as much as possible.
+ (*addsi_1): Likewise.
+ (return_internal): Set atom_unit.
+ (return_internal_long): Likewise.
+ (return_pop_internal): Likewise.
+ (*rcpsf2_sse): Set atom_sse_attr attr.
+ (*qrt<mode>2_sse): Likewise.
+
+2009-04-02 H.J. Lu <hongjiu.lu@intel.com>
+
+ Backport from mainline:
+ 2009-04-02 H.J. Lu <hongjiu.lu@intel.com>
+
+ * config/i386/i386.c (ix86_abi): Move initialization to ...
+ (override_options): Here.
+
+2009-03-29 H.J. Lu <hongjiu.lu@intel.com>
+
+ Backport from mainline:
+ 2009-03-29 H.J. Lu <hongjiu.lu@intel.com>
+
+ * config/i386/i386-protos.h (ix86_agi_dependent): New.
+
+ * config/i386/i386.c (ix86_agi_dependent): Rewrite.
+ (ix86_adjust_cost): Updated.
+
+2009-03-27 H.J. Lu <hongjiu.lu@intel.com>
+
+ Backport from mainline:
+ 2009-03-27 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR target/39472
+ * config/i386/i386.c (ix86_abi): New.
+ (override_options): Handle -mabi=.
+ (ix86_function_arg_regno_p): Replace DEFAULT_ABI with
+ ix86_abi.
+ (ix86_call_abi_override): Likewise.
+ (init_cumulative_args): Likewise.
+ (function_arg_advance): Likewise.
+ (function_arg_64): Likewise.
+ (function_arg): Likewise.
+ (ix86_pass_by_reference): Likewise.
+ (ix86_function_value_regno_p): Likewise.
+ (ix86_build_builtin_va_list_abi): Likewise.
+ (setup_incoming_varargs_64): Likewise.
+ (is_va_list_char_pointer): Likewise.
+ (ix86_init_machine_status): Likewise.
+ (ix86_reg_parm_stack_space): Use enum calling_abi on
+ call_abi.
+ (ix86_function_type_abi): Return enum calling_abi. Rewrite
+ for 64bit. Replace DEFAULT_ABI with ix86_abi.
+ (ix86_function_abi): Make it static and return enum
+ calling_abi.
+ (ix86_cfun_abi): Return enum calling_abi. Replace DEFAULT_ABI
+ with ix86_abi.
+ (ix86_fn_abi_va_list): Updated.
+
+ * config/i386/i386.h (ix86_abi): New.
+ (STACK_BOUNDARY): Replace DEFAULT_ABI with ix86_abi.
+ (CONDITIONAL_REGISTER_USAGE): Likewise.
+ (CUMULATIVE_ARGS): Change call_abi type to enum calling_abi.
+ (machine_function): Likewise.
+
+ * config/i386/i386.md (untyped_call): Replace DEFAULT_ABI
+ with ix86_abi.
+ * config/i386/cygming.h (TARGET_64BIT_MS_ABI): Likewise.
+ (STACK_BOUNDARY): Likewise.
+ * config/i386/mingw32.h (EXTRA_OS_CPP_BUILTINS): Likewise.
+
+ * config/i386/i386.opt (mabi=): New.
+
+ * config/i386/i386-protos.h (ix86_cfun_abi): Changed to
+ return enum calling_abi.
+ (ix86_function_type_abi): Likewise.
+ (ix86_function_abi): Removed.
+
+2009-03-27 H.J. Lu <hongjiu.lu@intel.com>
+
+ Backport from mainline:
+ 2009-03-27 Vladimir Makarov <vmakarov@redhat.com>
+
+ * genautomata.c: Add a new year to the copyright. Add a new
+ reference.
+ (struct insn_reserv_decl): Add comments for member bypass_list.
+ (find_bypass): Remove.
+ (insert_bypass): New.
+ (process_decls): Use insert_bypass.
+ (output_internal_insn_latency_func): Output all bypasses with the
+ same input insn in one switch case.
+
+ * rtl.def (define_bypass): Describe bypass choice.
+ * doc/md.texi (define_bypass): Ditto.
diff --git a/gcc-4.4.3/gcc/Makefile.in b/gcc-4.4.3/gcc/Makefile.in
index b506db902..974b016e1 100644
--- a/gcc-4.4.3/gcc/Makefile.in
+++ b/gcc-4.4.3/gcc/Makefile.in
@@ -555,6 +555,9 @@ objext = .o
exeext = @host_exeext@
build_exeext = @build_exeext@
+# Google-local http://b/2739909
+link_rpath_spec = @link_rpath_spec@
+
# Directory in which to put man pages.
mandir = @mandir@
man1dir = $(mandir)/man1
@@ -593,13 +596,24 @@ ifeq ($(inhibit_libc),true)
INHIBIT_LIBC_CFLAGS = -Dinhibit_libc
endif
+# We don't want __stack_chk_fail in crt* and libgcc2.a.
+# We don't want to compile crtbegin, crtend and crtbeginT with -fPIE.
+enable_esp = @enable_esp@
+ifeq ($(enable_esp),yes)
+ESP_NOPIE_CFLAGS = -fno-PIE
+ESP_NOSSP_CFLAGS = -fno-stack-protector
+else
+ESP_NOPIE_CFLAGS=
+ESP_NOSSP_CFLAGS=
+endif
+
# Options to use when compiling libgcc2.a.
#
LIBGCC2_DEBUG_CFLAGS = -g
LIBGCC2_CFLAGS = -O2 $(LIBGCC2_INCLUDES) $(GCC_CFLAGS) $(TARGET_LIBGCC2_CFLAGS) \
$(LIBGCC2_DEBUG_CFLAGS) $(GTHREAD_FLAGS) \
-DIN_LIBGCC2 -D__GCC_FLOAT_NOT_NEEDED \
- $(INHIBIT_LIBC_CFLAGS)
+ $(INHIBIT_LIBC_CFLAGS) $(ESP_NOSSP_CFLAGS)
# Additional options to use when compiling libgcc2.a.
# Some targets override this to -isystem include
@@ -610,9 +624,9 @@ TARGET_LIBGCC2_CFLAGS =
# Options to use when compiling crtbegin/end.
CRTSTUFF_CFLAGS = -O2 $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -g0 \
- -finhibit-size-directive -fno-inline-functions -fno-exceptions \
+ -finhibit-size-directive -fno-inline -fno-exceptions \
-fno-zero-initialized-in-bss -fno-toplevel-reorder -fno-tree-vectorize \
- $(INHIBIT_LIBC_CFLAGS)
+ $(INHIBIT_LIBC_CFLAGS) $(ESP_NOSSP_CFLAGS)
# Additional sources to handle exceptions; overridden by targets as needed.
LIB2ADDEH = $(srcdir)/unwind-dw2.c $(srcdir)/unwind-dw2-fde.c \
@@ -642,6 +656,12 @@ EXTRA_PROGRAMS = @extra_programs@
# The rules for compiling them should be in the t-* file for the machine.
EXTRA_PARTS = @extra_parts@
+# We add crtbeginTS.o to the EXTRA_PARTS list if enable_crtbeginTS = yes
+enable_crtbeginTS = @enable_crtbeginTS@
+ifeq ($(enable_crtbeginTS),yes)
+EXTRA_PARTS += crtbeginTS.o
+endif
+
# List of extra object files that should be compiled and linked with
# compiler proper (cc1, cc1obj, cc1plus).
EXTRA_OBJS = @extra_objs@
@@ -930,7 +950,7 @@ BUILD_LIBDEPS= $(BUILD_LIBIBERTY)
# How to link with both our special library facilities
# and the system's installed libraries.
LIBS = @LIBS@ $(CPPLIB) $(LIBINTL) $(LIBICONV) $(LIBIBERTY) $(LIBDECNUMBER)
-BACKENDLIBS = $(CLOOGLIBS) $(PPLLIBS) $(GMPLIBS) $(PLUGINLIBS)
+BACKENDLIBS = $(CLOOGLIBS) $(PPLLIBS) $(GMPLIBS) $(PLUGINLIBS) -lm
# Any system libraries needed just for GNAT.
SYSLIBS = @GNAT_LIBEXC@
@@ -1166,6 +1186,7 @@ OBJS-common = \
mcf.o \
mode-switching.o \
modulo-sched.o \
+ mversn-dispatch.o \
omega.o \
omp-low.o \
optabs.o \
@@ -1212,6 +1233,7 @@ OBJS-common = \
simplify-rtx.o \
sparseset.o \
sreal.o \
+ tree-stack-overlay.o \
stack-ptr-mod.o \
statistics.o \
stmt.o \
@@ -1368,13 +1390,14 @@ MOSTLYCLEANFILES = insn-flags.h insn-config.h insn-codes.h \
LIB2FUNCS_ST = _eprintf __gcc_bcmp
# Defined in libgcov.c, included only in gcov library
-LIBGCOV = _gcov _gcov_merge_add _gcov_merge_single _gcov_merge_delta \
- _gcov_fork _gcov_execl _gcov_execlp _gcov_execle \
+LIBGCOV = _gcov _gcov_merge_add _gcov_merge_single _gcov_merge_single_float \
+ _gcov_merge_delta _gcov_fork _gcov_execl _gcov_execlp _gcov_execle \
_gcov_execv _gcov_execvp _gcov_execve \
_gcov_interval_profiler _gcov_pow2_profiler _gcov_one_value_profiler \
- _gcov_indirect_call_profiler _gcov_direct_call_profiler \
- _gcov_average_profiler _gcov_ior_profiler _gcov_merge_ior _gcov_merge_dc \
- _gcov_merge_icall_topn _gcov_indirect_call_topn_profiler
+ _gcov_one_float_value_profiler _gcov_indirect_call_profiler \
+ _gcov_direct_call_profiler _gcov_average_profiler _gcov_ior_profiler \
+ _gcov_merge_ior _gcov_merge_dc _gcov_merge_icall_topn \
+ _gcov_indirect_call_topn_profiler _gcov_merge_reusedist
FPBIT_FUNCS = _pack_sf _unpack_sf _addsub_sf _mul_sf _div_sf \
_fpcmp_parts_sf _compare_sf _eq_sf _ne_sf _gt_sf _ge_sf \
@@ -1743,8 +1766,9 @@ libgcc.mvars: config.status Makefile $(LIB2ADD) $(LIB2ADD_ST) specs \
echo LIBGCC_SYNC = '$(LIBGCC_SYNC)' >> tmp-libgcc.mvars
echo LIBGCC_SYNC_CFLAGS = '$(LIBGCC_SYNC_CFLAGS)' >> tmp-libgcc.mvars
echo CRTSTUFF_CFLAGS = '$(CRTSTUFF_CFLAGS)' >> tmp-libgcc.mvars
- echo CRTSTUFF_T_CFLAGS = '$(CRTSTUFF_T_CFLAGS)' >> tmp-libgcc.mvars
+ echo CRTSTUFF_T_CFLAGS = '$(CRTSTUFF_T_CFLAGS) $(ESP_NOPIE_CFLAGS)' >> tmp-libgcc.mvars
echo CRTSTUFF_T_CFLAGS_S = '$(CRTSTUFF_T_CFLAGS_S)' >> tmp-libgcc.mvars
+ echo enable_crtbeginTS = '$(enable_crtbeginTS)' >> tmp-libgcc.mvars
mv tmp-libgcc.mvars libgcc.mvars
@@ -1778,12 +1802,14 @@ s-mlib: $(srcdir)/genmultilib Makefile
$(T)crtbegin.o: crtstuff.c $(GCC_PASSES) $(TCONFIG_H) auto-host.h \
gbl-ctors.h stmp-int-hdrs tsystem.h coretypes.h $(TM_H)
$(GCC_FOR_TARGET) $(CRTSTUFF_CFLAGS) $(CRTSTUFF_T_CFLAGS) \
+ $(ESP_NOPIE_CFLAGS) \
-c $(srcdir)/crtstuff.c -DCRT_BEGIN \
-o $(T)crtbegin$(objext)
$(T)crtend.o: crtstuff.c $(GCC_PASSES) $(TCONFIG_H) auto-host.h \
gbl-ctors.h stmp-int-hdrs tsystem.h coretypes.h $(TM_H)
$(GCC_FOR_TARGET) $(CRTSTUFF_CFLAGS) $(CRTSTUFF_T_CFLAGS) \
+ $(ESP_NOPIE_CFLAGS) \
-c $(srcdir)/crtstuff.c -DCRT_END \
-o $(T)crtend$(objext)
@@ -1804,9 +1830,19 @@ $(T)crtendS.o: crtstuff.c $(GCC_PASSES) $(TCONFIG_H) auto-host.h \
$(T)crtbeginT.o: crtstuff.c $(GCC_PASSES) $(TCONFIG_H) auto-host.h \
gbl-ctors.h stmp-int-hdrs tsystem.h coretypes.h $(TM_H)
$(GCC_FOR_TARGET) $(CRTSTUFF_CFLAGS) $(CRTSTUFF_T_CFLAGS) \
+ $(ESP_NOPIE_CFLAGS) \
-c $(srcdir)/crtstuff.c -DCRT_BEGIN -DCRTSTUFFT_O \
-o $(T)crtbeginT$(objext)
+# This is a version of crtbegin for -static -fPIE links if espf is enable.
+ifeq ($(enable_crtbeginTS),yes)
+$(T)crtbeginTS.o: crtstuff.c $(GCC_PASSES) $(TCONFIG_H) auto-host.h \
+ gbl-ctors.h stmp-int-hdrs tsystem.h coretypes.h $(TM_H)
+ $(GCC_FOR_TARGET) $(CRTSTUFF_CFLAGS) $(CRTSTUFF_T_CFLAGS_S) \
+ -c $(srcdir)/crtstuff.c -DCRT_BEGIN -DCRTSTUFFT_O -DCRTSTUFFS_O \
+ -o $(T)crtbeginTS$(objext)
+endif
+
# Compile the start modules crt0.o and mcrt0.o that are linked with
# every program
$(T)crt0.o: s-crt0 ; @true
@@ -1924,7 +1960,7 @@ 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_INLINE_H) $(DIAGNOSTIC_H) intl.h debug.h $(C_COMMON_H) \
opts.h options.h $(MKDEPS_H) incpath.h cppdefault.h $(TARGET_H) \
- $(TM_P_H) $(VARRAY_H) $(FUNCTION_H)
+ $(TM_P_H) $(VARRAY_H) $(FUNCTION_H) $(PARAMS_H)
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) \
$< $(OUTPUT_OPTION) @TARGET_SYSTEM_ROOT_DEFINE@
@@ -1976,6 +2012,7 @@ DRIVER_DEFINES = \
-DDEFAULT_TARGET_MACHINE=\"$(target_noncanonical)\" \
-DSTANDARD_BINDIR_PREFIX=\"$(bindir)/\" \
-DTOOLDIR_BASE_PREFIX=\"$(libsubdir_to_prefix)$(prefix_to_exec_prefix)\" \
+ -DLINK_RPATH_SPEC="\" $(link_rpath_spec) \"" \
@RUNTIME_ROOT_PREFIX_DEFINE@ \
@TARGET_SYSTEM_ROOT_DEFINE@ \
$(VALGRIND_DRIVER_DEFINES) \
@@ -2727,6 +2764,11 @@ implicit-zee.o : implicit-zee.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RT
$(DF_H) $(TIMEVAR_H) tree-pass.h $(RECOG_H) $(EXPR_H) \
$(REGS_H) $(TREE_H) $(TM_P_H) insn-config.h $(INSN_ATTR_H) $(REAL_H) $(TOPLEV_H) \
$(TARGET_H) $(OPTABS_H) insn-codes.h rtlhooks-def.h $(PARAMS_H) $(CGRAPH_H)
+mversn-dispatch.o : mversn-dispatch.c $(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 \
+ $(HASHTAB_H) $(COVERAGE_H) $(GGC_H) $(TREE_FLOW_H) $(RTL_H) $(IPA_PROP_H) \
+ $(BASIC_BLOCK_H) $(TOPLEV_H) $(TREE_DUMP_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) \
@@ -2835,7 +2877,7 @@ 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 $(TREE_INLINE_H) $(TARGET_H)
+ value-prof.h $(TREE_INLINE_H) $(TARGET_H) tree-stack-overlay.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_ATTR_H) \
@@ -2942,6 +2984,11 @@ alias.o : alias.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_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
+tree-stack-overlay.o : tree-stack-overlay.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) \
+ $(TARGET_H) tree-stack-overlay.h gt-tree-stack-overlay.h $(GGC_H)
stack-ptr-mod.o : stack-ptr-mod.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(TREE_H) $(RTL_H) $(REGS_H) $(EXPR_H) tree-pass.h \
$(BASIC_BLOCK_H) $(FLAGS_H) output.h $(DF_H)
@@ -3114,7 +3161,7 @@ $(out_object_file): $(out_file) $(CONFIG_H) coretypes.h $(TM_H) $(TREE_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 $(GIMPLE_H)
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) \
+ $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(ESP_NOSSP_CFLAGS)\
$(out_file) $(OUTPUT_OPTION)
# Build auxiliary files that support ecoff format.
@@ -3366,6 +3413,7 @@ GTFILES = $(CPP_ID_DATA_H) $(srcdir)/input.h $(srcdir)/coretypes.h \
$(srcdir)/tree-phinodes.c \
$(srcdir)/ipa-reference.c $(srcdir)/tree-ssa-structalias.h \
$(srcdir)/tree-ssa-structalias.c $(srcdir)/tree-inline.c \
+ $(srcdir)/tree-stack-overlay.c \
@all_gtfiles@
# Compute the list of GT header files from the corresponding C sources,
@@ -4191,7 +4239,7 @@ PLUGIN_HEADERS = $(TREE_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(host_xm_file_list) $(host_xm_include_list) $(xm_include_list) \
intl.h $(PLUGIN_VERSION_H) $(DIAGNOSTIC_H) $(C_COMMON_H) $(C_PRETTY_PRINT_H) \
tree-iterator.h $(PLUGIN_H) $(TREE_FLOW_H) langhooks.h incpath.h \
- tree-ssa-sccvn.h real.h output.h $(IPA_UTILS_H)
+ tree-ssa-sccvn.h real.h output.h $(IPA_UTILS_H) $(CFGLOOP_H)
# Install the headers needed to build a plugin.
install-plugin: installdirs lang.install-plugin
diff --git a/gcc-4.4.3/gcc/attribs.c b/gcc-4.4.3/gcc/attribs.c
index d8ac372e5..ad30d7971 100644
--- a/gcc-4.4.3/gcc/attribs.c
+++ b/gcc-4.4.3/gcc/attribs.c
@@ -541,6 +541,11 @@ is_lock_attribute_p (tree identifier)
if (is_lock_attribute_with_args (identifier)
|| is_attribute_p ("no_thread_safety_analysis", identifier)
+ || is_attribute_p ("ignore_reads_begin", identifier)
+ || is_attribute_p ("ignore_reads_end", identifier)
+ || is_attribute_p ("ignore_writes_begin", identifier)
+ || is_attribute_p ("ignore_writes_end", identifier)
+ || is_attribute_p ("unprotected_read", identifier)
|| is_attribute_p ("guarded", identifier)
|| is_attribute_p ("point_to_guarded", identifier)
|| is_attribute_p ("lockable", identifier)
diff --git a/gcc-4.4.3/gcc/builtin-types.def b/gcc-4.4.3/gcc/builtin-types.def
index 4676dd764..bf86ae797 100644
--- a/gcc-4.4.3/gcc/builtin-types.def
+++ b/gcc-4.4.3/gcc/builtin-types.def
@@ -473,3 +473,7 @@ DEF_FUNCTION_TYPE_VAR_5 (BT_FN_INT_INT_INT_INT_INT_INT_VAR,
DEF_POINTER_TYPE (BT_PTR_FN_VOID_VAR, BT_FN_VOID_VAR)
DEF_FUNCTION_TYPE_3 (BT_FN_PTR_PTR_FN_VOID_VAR_PTR_SIZE,
BT_PTR, BT_PTR_FN_VOID_VAR, BT_PTR, BT_SIZE)
+
+DEF_POINTER_TYPE (BT_PTR_FN_INT, BT_FN_INT)
+DEF_FUNCTION_TYPE_VAR_3 (BT_FN_INT_PTR_FN_INT_PTR_PTR_VAR,
+ BT_INT, BT_PTR_FN_INT, BT_PTR, BT_PTR)
diff --git a/gcc-4.4.3/gcc/builtins.def b/gcc-4.4.3/gcc/builtins.def
index 7a98c7639..16c3a6ee5 100644
--- a/gcc-4.4.3/gcc/builtins.def
+++ b/gcc-4.4.3/gcc/builtins.def
@@ -758,6 +758,9 @@ DEF_BUILTIN (BUILT_IN_EMUTLS_REGISTER_COMMON,
true, true, true, ATTR_NOTHROW_LIST, false,
!targetm.have_tls)
+/* Multiversioning builtin dispatch hook. */
+DEF_GCC_BUILTIN (BUILT_IN_DISPATCH, "dispatch", BT_FN_INT_PTR_FN_INT_PTR_PTR_VAR, ATTR_NULL)
+
/* Synchronization Primitives. */
#include "sync-builtins.def"
diff --git a/gcc-4.4.3/gcc/c-common.c b/gcc-4.4.3/gcc/c-common.c
index 03f4d3451..8f5db0d38 100644
--- a/gcc-4.4.3/gcc/c-common.c
+++ b/gcc-4.4.3/gcc/c-common.c
@@ -523,6 +523,7 @@ static tree check_case_value (tree);
static bool check_case_bounds (tree, tree, tree *, tree *);
static tree handle_packed_attribute (tree *, tree, tree, int, bool *);
+static tree handle_version_selector_attribute (tree *, tree, tree, int, bool *);
static tree handle_nocommon_attribute (tree *, tree, tree, int, bool *);
static tree handle_common_attribute (tree *, tree, tree, int, bool *);
static tree handle_noreturn_attribute (tree *, tree, tree, int, bool *);
@@ -775,6 +776,8 @@ const unsigned int num_c_common_reswords =
const struct attribute_spec c_common_attribute_table[] =
{
/* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
+ { "version_selector", 0, 0, true, false, false,
+ handle_version_selector_attribute },
{ "packed", 0, 0, false, false, false,
handle_packed_attribute },
{ "nocommon", 0, 0, true, false, false,
@@ -914,6 +917,16 @@ const struct attribute_spec c_common_attribute_table[] =
handle_lock_returned_attribute },
{ "no_thread_safety_analysis", 0, 0, true, false, false,
handle_no_thread_safety_analysis_attribute },
+ { "ignore_reads_begin", 0, 0, true, false, false,
+ handle_no_thread_safety_analysis_attribute },
+ { "ignore_reads_end", 0, 0, true, false, false,
+ handle_no_thread_safety_analysis_attribute },
+ { "ignore_writes_begin", 0, 0, true, false, false,
+ handle_no_thread_safety_analysis_attribute },
+ { "ignore_writes_end", 0, 0, true, false, false,
+ handle_no_thread_safety_analysis_attribute },
+ { "unprotected_read", 0, 0, true, false, false,
+ handle_no_thread_safety_analysis_attribute },
{ NULL, 0, 0, false, false, false, NULL }
};
@@ -5211,6 +5224,37 @@ handle_packed_attribute (tree *node, tree name, tree ARG_UNUSED (args),
return NULL_TREE;
}
+/* Handle a "version_selector attribute".
+ Functions are marked with attribute "version_selector" only if
+ they are run-time constants. Example of such functions would
+ be those that test if a particular feature is available on a
+ particular architecture. Such function must return a positive
+ integer. For two-way functions, those that test if a feature
+ is present or not must return 1 or 0 respectively. */
+
+static tree
+handle_version_selector_attribute (tree *node, tree name,
+ tree ARG_UNUSED (args),
+ int ARG_UNUSED (flags),
+ bool *no_add_attrs)
+{
+ if (TREE_CODE (*node) == FUNCTION_DECL)
+ {
+ /* Check that the return type is integer. */
+ gcc_assert (TREE_CODE (TREE_TYPE (TREE_TYPE (*node)))
+ == INTEGER_TYPE);
+ if (dump_file)
+ fprintf (dump_file, "%s is a version_selector function\n",
+ IDENTIFIER_POINTER (DECL_NAME (*node)));
+ }
+ else
+ {
+ warning (OPT_Wattributes, "%qE attribute ignored", name);
+ *no_add_attrs = true;
+ }
+ return NULL_TREE;
+}
+
/* Handle a "nocommon" attribute; arguments as in
struct attribute_spec.handler. */
@@ -6696,7 +6740,7 @@ handle_nonnull_attribute (tree *node, tree ARG_UNUSED (name),
/* Argument list specified. Verify that each argument number references
a pointer argument. */
- for (attr_arg_num = 1; args; args = TREE_CHAIN (args))
+ for (attr_arg_num = 1; args; args = TREE_CHAIN (args), attr_arg_num++)
{
tree argument;
unsigned HOST_WIDE_INT arg_num = 0, ck_num;
@@ -6728,6 +6772,7 @@ handle_nonnull_attribute (tree *node, tree ARG_UNUSED (name),
return NULL_TREE;
}
+
if (TREE_CODE (TREE_VALUE (argument)) != POINTER_TYPE)
{
error ("nonnull argument references non-pointer operand (argument %lu, operand %lu)",
@@ -6735,6 +6780,11 @@ handle_nonnull_attribute (tree *node, tree ARG_UNUSED (name),
*no_add_attrs = true;
return NULL_TREE;
}
+
+ if (TREE_CODE (type) == METHOD_TYPE && arg_num == 1)
+ warning (OPT_Wattributes,
+ "nonnull argument references 'this' pointer (argument %lu, operand %lu)",
+ (unsigned long) attr_arg_num, (unsigned long) arg_num);
}
}
@@ -7374,14 +7424,9 @@ static tree
handle_point_to_guarded_by_attribute (tree *node, tree name, tree args,
int flags, bool *no_add_attrs)
{
- /* point_to_guarded_by attribute can only annotate a pointer. */
- if (!POINTER_TYPE_P (TREE_TYPE (*node)))
- {
- warning (OPT_Wattributes,
- "%qE attribute ignored for a non-pointer", name);
- *no_add_attrs = true;
- return NULL_TREE;
- }
+ /* We used to check if the point_to_guarded_by attribute is applied to
+ a pointer, but no longer do that as we now allow the attribute to
+ be applied to smart/scoped pointer objects. */
/* The rest of the handler is identical to the handler for
the guarded_by attr. */
@@ -7414,14 +7459,9 @@ static tree
handle_point_to_guarded_attribute (tree *node, tree name, tree args,
int flags, bool *no_add_attrs)
{
- /* point_to_guarded attribute can only annotate a pointer. */
- if (!POINTER_TYPE_P (TREE_TYPE (*node)))
- {
- warning (OPT_Wattributes,
- "%qE attribute ignored for a non-pointer", name);
- *no_add_attrs = true;
- return NULL_TREE;
- }
+ /* We used to check if the point_to_guarded attribute is applied to
+ a pointer, but no longer do that as we now allow the attribute to
+ be applied to smart/scoped pointer objects. */
/* The rest of the handler is identical to the handler for guarded attr. */
return handle_guarded_attribute (node, name, args, flags, no_add_attrs);
diff --git a/gcc-4.4.3/gcc/c-cppbuiltin.c b/gcc-4.4.3/gcc/c-cppbuiltin.c
index 974b257b1..0fda7993b 100644
--- a/gcc-4.4.3/gcc/c-cppbuiltin.c
+++ b/gcc-4.4.3/gcc/c-cppbuiltin.c
@@ -669,7 +669,10 @@ c_cpp_builtins (cpp_reader *pfile)
/* Define a macro indicating whether the thread safety attributes/analysis
is supported. */
if (warn_thread_safety)
- cpp_define (pfile, "__SUPPORT_TS_ANNOTATION__");
+ {
+ cpp_define (pfile, "__SUPPORT_TS_ANNOTATION__");
+ cpp_define (pfile, "__SUPPORT_DYN_ANNOTATION__");
+ }
/* Tell source code if the compiler makes sync_compare_and_swap
builtins available. */
diff --git a/gcc-4.4.3/gcc/c-opts.c b/gcc-4.4.3/gcc/c-opts.c
index c0262b93c..82290a8eb 100644
--- a/gcc-4.4.3/gcc/c-opts.c
+++ b/gcc-4.4.3/gcc/c-opts.c
@@ -41,6 +41,7 @@ along with GCC; see the file COPYING3. If not see
#include "target.h"
#include "tm_p.h"
#include "function.h"
+#include "params.h"
#ifndef DOLLARS_IN_IDENTIFIERS
# define DOLLARS_IN_IDENTIFIERS true
@@ -405,6 +406,7 @@ c_common_handle_option (size_t scode, const char *arg, int value)
warning about not using it without also specifying -O. */
if (warn_uninitialized != 1)
warn_uninitialized = (value ? 2 : 0);
+ warn_maybe_uninitialized = value;
if (!c_dialect_cxx ())
{
@@ -1096,9 +1098,9 @@ c_common_post_options (const char **pfilename)
warn_sign_conversion = (c_dialect_cxx ()) ? 0 : warn_conversion;
/* Enable warning for null conversion when -Wconversion is specified (unless
- disabled through -Wno-null-conversion). */
- if (warn_null_conversion == -1)
- warn_null_conversion = warn_conversion;
+ disabled through -Wno-conversion-null). */
+ if (warn_conversion_null == -1)
+ warn_conversion_null = warn_conversion;
/* Enable warning for converting real values to integral values
when -Wconversion is specified (unless disabled through
@@ -1229,6 +1231,28 @@ c_common_init (void)
return true;
}
+/* Return TRUE if the lipo maximum memory consumption limit is reached, and
+ we should not import any further auxiliary modules. Check after parsing
+ each module, the Ith module being the just parsed module. */
+static bool
+lipo_max_mem_reached (unsigned int i)
+{
+ if (L_IPO_COMP_MODE && PARAM_VALUE (PARAM_MAX_LIPO_MEMORY)
+ && i < (num_in_fnames - 1)
+ && ((ggc_total_allocated () >> 10)
+ > (size_t) PARAM_VALUE (PARAM_MAX_LIPO_MEMORY))) {
+ i++;
+ do {
+ inform (input_location, "Not importing %s: maximum memory "
+ "consumption reached", in_fnames[i]);
+ i++;
+ } while (i < num_in_fnames);
+ return true;
+ }
+ return false;
+}
+
+
/* Initialize the integrated preprocessor after debug output has been
initialized; loop over each input file. */
void
@@ -1270,6 +1294,12 @@ c_common_parse_file (int set_yydebug)
set_lipo_c_parsing_context (parse_in, i, verbose);
push_file_scope ();
c_parse_file ();
+ /* In lipo mode, processing too many auxiliary files will cause us
+ to hit memory limits, and cause thrashing -- prevent this by not
+ processing any further auxiliary modules if we reach a certain
+ memory limit. */
+ if (lipo_max_mem_reached (i))
+ num_in_fnames = i + 1;
finish_file ();
pop_file_scope ();
/* And end the main input file, if the debug writer wants it */
diff --git a/gcc-4.4.3/gcc/c.opt b/gcc-4.4.3/gcc/c.opt
index 0d6baf8b1..81610a95f 100644
--- a/gcc-4.4.3/gcc/c.opt
+++ b/gcc-4.4.3/gcc/c.opt
@@ -171,14 +171,18 @@ Wconversion
C ObjC C++ ObjC++ Var(warn_conversion) Warning
Warn for implicit type conversions that may change a value
-Wnull-conversion
-C ObjC C++ ObjC++ Var(warn_null_conversion) Init(-1) Warning
+Wconversion-null
+C++ ObjC++ Var(warn_conversion_null) Init(-1) Warning
Warn about peculiar, but valid, conversions from/to NULL
Wreal-conversion
C ObjC C++ ObjC++ Var(warn_real_conversion) Init(-1) Warning
Warn for implicit type conversions from real to integral values
+Wself-assign-non-pod
+C++ ObjC++ Var(warn_self_assign_non_pod) Init(0) Warning
+Warn when a variable of a non-POD type is assigned to itself
+
Wsign-conversion
C ObjC C++ ObjC++ Var(warn_sign_conversion) Init(-1)
Warn for implicit type conversions between signed and unsigned integers
@@ -345,7 +349,7 @@ C++ ObjC++ Var(warn_nonvdtor) Warning
Warn about non-virtual destructors
Wnonnull
-C ObjC Var(warn_nonnull) Warning
+C C++ ObjC ObjC++ Var(warn_nonnull) Warning
Warn about NULL being passed to argument slots marked as requiring non-NULL
Wnormalized=
diff --git a/gcc-4.4.3/gcc/caller-save.c b/gcc-4.4.3/gcc/caller-save.c
index 0c840c308..92e03f0c8 100644
--- a/gcc-4.4.3/gcc/caller-save.c
+++ b/gcc-4.4.3/gcc/caller-save.c
@@ -143,7 +143,7 @@ reg_save_code (int reg, enum machine_mode mode)
/* Update the register number and modes of the register
and memory operand. */
- SET_REGNO (test_reg, reg);
+ SET_REGNO_RAW (test_reg, reg);
PUT_MODE (test_reg, mode);
PUT_MODE (test_mem, mode);
diff --git a/gcc-4.4.3/gcc/calls.c b/gcc-4.4.3/gcc/calls.c
index 1cdc480cf..ff3ea9c35 100644
--- a/gcc-4.4.3/gcc/calls.c
+++ b/gcc-4.4.3/gcc/calls.c
@@ -2004,7 +2004,7 @@ expand_call (tree exp, rtx target, int ignore)
#ifdef REG_PARM_STACK_SPACE
/* Define the boundary of the register parm stack space that needs to be
saved, 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
@@ -3812,7 +3812,7 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
cse'ing of library calls could delete a call and leave the pop. */
NO_DEFER_POP;
valreg = (mem_value == 0 && outmode != VOIDmode
- ? hard_libcall_value (outmode) : NULL_RTX);
+ ? hard_libcall_value (outmode, orgfun) : NULL_RTX);
/* Stack must be properly aligned now. */
gcc_assert (!(stack_pointer_delta
diff --git a/gcc-4.4.3/gcc/cfgexpand.c b/gcc-4.4.3/gcc/cfgexpand.c
index d63701a7d..66acd3c75 100644
--- a/gcc-4.4.3/gcc/cfgexpand.c
+++ b/gcc-4.4.3/gcc/cfgexpand.c
@@ -42,7 +42,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-inline.h"
#include "value-prof.h"
#include "target.h"
-
+#include "tree-stack-overlay.h"
/* Return an expression tree corresponding to the RHS of GIMPLE
statement STMT. */
@@ -871,6 +871,21 @@ dump_stack_var_partition (void)
}
}
+static void
+sort_stack_vars (void)
+{
+ size_t si, n = stack_vars_num;
+
+ stack_vars_sorted = XNEWVEC (size_t, stack_vars_num);
+ for (si = 0; si < n; ++si)
+ stack_vars_sorted[si] = si;
+
+ if (n == 1)
+ return;
+
+ qsort (stack_vars_sorted, n, sizeof (size_t), stack_var_size_cmp);
+}
+
/* Assign rtl to DECL at frame offset OFFSET. */
static void
@@ -896,6 +911,34 @@ expand_one_stack_var_at (tree decl, HOST_WIDE_INT offset)
set_mem_attributes (x, decl, true);
SET_DECL_RTL (decl, x);
+ if (flag_early_stack_alloc)
+ {
+ /* If this decl is synthesized by stack_overlay pass, copy the RTL
+ to the original DECLs and remove this decl from BLOCK_VARS to
+ generate proper debug info. */
+ VEC(tree,gc) *orig_vars = get_original_stack_vars (decl);
+ if (VEC_length(tree,orig_vars))
+ {
+ tree t, outer_block = DECL_INITIAL (current_function_decl);
+ int ix=0;
+ /* Set RTL to original variables. */
+ for (ix = 0; VEC_iterate(tree,orig_vars,ix,t); ix++)
+ SET_DECL_RTL (t, x);
+ /* Remove decl from BLOCK_VARS. */
+ t = BLOCK_VARS (outer_block);
+ if (t == decl)
+ BLOCK_VARS (outer_block) = TREE_CHAIN (t);
+ else
+ {
+ for (; t ; t = TREE_CHAIN (t))
+ if (TREE_CHAIN (t) == decl)
+ {
+ TREE_CHAIN (t) = TREE_CHAIN (decl);
+ break;
+ }
+ }
+ }
+ }
}
/* A subroutine of expand_used_vars. Give each partition representative
@@ -1045,6 +1088,11 @@ defer_stack_allocation (tree var, bool toplevel)
if (flag_stack_protect)
return true;
+ /* If stack protection is not required and variable coalescing happens
+ in an earlier pass, no need to defer allocation. */
+ if (flag_early_stack_alloc)
+ return false;
+
/* Variables in the outermost scope automatically conflict with
every other variable. The only reason to want to defer them
at all is that, after sorting, we can more efficiently pack
@@ -1064,6 +1112,7 @@ defer_stack_allocation (tree var, bool toplevel)
return true;
}
+
/* A subroutine of expand_used_vars. Expand one variable according to
its flavor. Variables to be placed on the stack are not actually
expanded yet, merely recorded.
@@ -1282,12 +1331,25 @@ stack_protect_decl_phase (tree decl)
else
ret = (bits & SPCT_HAS_LARGE_CHAR_ARRAY) != 0;
- if (ret)
+ if (!flag_early_stack_alloc && ret)
has_protected_decls = true;
return ret;
}
+static bool
+need_stack_protection (void)
+{
+ size_t i, n = stack_vars_num;
+
+ if (!flag_stack_protect)
+ return false;
+ for (i = 0; i < n; ++i)
+ if (stack_protect_decl_phase (stack_vars[i].decl))
+ return true;
+ return false;
+}
+
/* Two helper routines that check for phase 1 and phase 2. These are used
as callbacks for expand_stack_vars. */
@@ -1475,35 +1537,37 @@ expand_used_vars (void)
for (; t; t = next)
{
tree var = TREE_VALUE (t);
- bool expand_now = false;
+ bool expand_now = flag_early_stack_alloc;
next = TREE_CHAIN (t);
-
- /* We didn't set a block for static or extern because it's hard
- to tell the difference between a global variable (re)declared
- in a local scope, and one that's really declared there to
- begin with. And it doesn't really matter much, since we're
- not giving them stack space. Expand them now. */
- if (TREE_STATIC (var) || DECL_EXTERNAL (var))
- expand_now = true;
-
- /* Any variable that could have been hoisted into an SSA_NAME
- will have been propagated anywhere the optimizers chose,
- i.e. not confined to their original block. Allocate them
- as if they were defined in the outermost scope. */
- else if (is_gimple_reg (var))
- expand_now = true;
-
- /* If the variable is not associated with any block, then it
- was created by the optimizers, and could be live anywhere
- in the function. */
- else if (TREE_USED (var))
- expand_now = true;
-
- /* Finally, mark all variables on the list as used. We'll use
- this in a moment when we expand those associated with scopes. */
- TREE_USED (var) = 1;
-
+ if (!flag_early_stack_alloc)
+ {
+ /* We didn't set a block for static or extern because it's hard
+ to tell the difference between a global variable (re)declared
+ in a local scope, and one that's really declared there to
+ begin with. And it doesn't really matter much, since we're
+ not giving them stack space. Expand them now. */
+ if (TREE_STATIC (var) || DECL_EXTERNAL (var))
+ expand_now = true;
+
+ /* Any variable that could have been hoisted into an SSA_NAME
+ will have been propagated anywhere the optimizers chose,
+ i.e. not confined to their original block. Allocate them
+ as if they were defined in the outermost scope. */
+ else if (is_gimple_reg (var))
+ expand_now = true;
+
+ /* If the variable is not associated with any block, then it
+ was created by the optimizers, and could be live anywhere
+ in the function. */
+ else if (TREE_USED (var))
+ expand_now = true;
+
+ /* Finally, mark all variables on the list as used. We'll use
+ this in a moment when we expand those associated with scopes. */
+ TREE_USED (var) = 1;
+
+ }
if (expand_now)
{
expand_one_var (var, true, true);
@@ -1525,11 +1589,14 @@ expand_used_vars (void)
ggc_free (t);
}
- /* At this point, all variables within the block tree with TREE_USED
- set are actually used by the optimized function. Lay them out. */
- expand_used_vars_for_block (outer_block, true);
+ if (flag_early_stack_alloc)
+ has_protected_decls = need_stack_protection ();
+ else
+ /* At this point, all variables within the block tree with TREE_USED
+ set are actually used by the optimized function. Lay them out. */
+ expand_used_vars_for_block (outer_block, true);
- if (stack_vars_num > 0)
+ if (!flag_early_stack_alloc && stack_vars_num > 0)
{
/* Due to the way alias sets work, no variables with non-conflicting
alias sets may be assigned the same address. Add conflicts to
@@ -1558,6 +1625,8 @@ expand_used_vars (void)
/* Assign rtl to each variable based on these partitions. */
if (stack_vars_num > 0)
{
+ if (flag_early_stack_alloc)
+ sort_stack_vars ();
/* Reorder decls to be protected by iterating over the variables
array multiple times, and allocating out of each phase in turn. */
/* ??? We could probably integrate this into the qsort we did
@@ -2245,8 +2314,18 @@ expand_stack_alignment (void)
|| crtl->has_nonlocal_goto)
crtl->need_drap = true;
- gcc_assert (crtl->stack_alignment_needed
- <= crtl->stack_alignment_estimated);
+ /* Call update_stack_boundary here again to update incoming stack
+ boundary. It may set incoming stack alignment to a different
+ value after RTL expansion. TARGET_FUNCTION_OK_FOR_SIBCALL may
+ use the minimum incoming stack alignment to check if it is OK
+ to perform sibcall optimization since sibcall optimization will
+ only align the outgoing stack to incoming stack boundary. */
+ if (targetm.calls.update_stack_boundary)
+ targetm.calls.update_stack_boundary ();
+
+ /* The incoming stack frame has to be aligned at least at
+ parm_stack_boundary. */
+ gcc_assert (crtl->parm_stack_boundary <= INCOMING_STACK_BOUNDARY);
/* Update crtl->stack_alignment_estimated and use it later to align
stack. We check PREFERRED_STACK_BOUNDARY if there may be non-call
@@ -2262,6 +2341,9 @@ expand_stack_alignment (void)
if (preferred_stack_boundary > crtl->stack_alignment_needed)
crtl->stack_alignment_needed = preferred_stack_boundary;
+ gcc_assert (crtl->stack_alignment_needed
+ <= crtl->stack_alignment_estimated);
+
crtl->stack_realign_needed
= INCOMING_STACK_BOUNDARY < crtl->stack_alignment_estimated;
crtl->stack_realign_tried = crtl->stack_realign_needed;
@@ -2333,7 +2415,7 @@ gimple_expand_cfg (void)
targetm.expand_to_rtl_hook ();
crtl->stack_alignment_needed = STACK_BOUNDARY;
crtl->max_used_stack_slot_alignment = STACK_BOUNDARY;
- crtl->stack_alignment_estimated = STACK_BOUNDARY;
+ crtl->stack_alignment_estimated = 0;
crtl->preferred_stack_boundary = STACK_BOUNDARY;
cfun->cfg->max_jumptable_ents = 0;
@@ -2368,23 +2450,6 @@ gimple_expand_cfg (void)
if (crtl->stack_protect_guard)
stack_protect_prologue ();
- /* Update stack boundary if needed. */
- if (SUPPORTS_STACK_ALIGNMENT)
- {
- /* Call update_stack_boundary here to update incoming stack
- boundary before TARGET_FUNCTION_OK_FOR_SIBCALL is called.
- TARGET_FUNCTION_OK_FOR_SIBCALL needs to know the accurate
- incoming stack alignment to check if it is OK to perform
- sibcall optimization since sibcall optimization will only
- align the outgoing stack to incoming stack boundary. */
- if (targetm.calls.update_stack_boundary)
- targetm.calls.update_stack_boundary ();
-
- /* The incoming stack frame has to be aligned at least at
- parm_stack_boundary. */
- gcc_assert (crtl->parm_stack_boundary <= INCOMING_STACK_BOUNDARY);
- }
-
/* Register rtl specific functions for cfg. */
rtl_register_cfg_hooks ();
diff --git a/gcc-4.4.3/gcc/cgraph.c b/gcc-4.4.3/gcc/cgraph.c
index 96b4662cd..77e1bd0fd 100644
--- a/gcc-4.4.3/gcc/cgraph.c
+++ b/gcc-4.4.3/gcc/cgraph.c
@@ -440,7 +440,7 @@ cgraph_create_node (void)
if (cgraph_nodes)
cgraph_nodes->previous = node;
node->previous = NULL;
- node->global.estimated_growth = INT_MIN;
+ node->global.estimated_average_growth = INT_MIN;
cgraph_nodes = node;
cgraph_n_nodes++;
return node;
@@ -1005,6 +1005,7 @@ cgraph_remove_node (struct cgraph_node *node)
cgraph_call_node_removal_hooks (node);
cgraph_node_remove_callers (node);
cgraph_node_remove_callees (node);
+ cgraph_remove_pid (node);
/* Incremental inlining access removed nodes stored in the postorder list.
*/
@@ -1118,6 +1119,15 @@ cgraph_mark_needed_node (struct cgraph_node *node)
cgraph_mark_reachable_node (node);
}
+/* Indicate that the address of the function represented by the node
+ has been taken. */
+
+void
+cgraph_mark_address_taken (struct cgraph_node *node)
+{
+ node->address_taken = 1;
+}
+
/* Return local info for the compiled function. */
struct cgraph_local_info *
@@ -1756,4 +1766,25 @@ dump_vcg_cgraph (FILE *fp, int min_count, bool weighted)
free (include_node);
}
+/* Return true if NODE is a hot function. */
+
+bool
+hot_function_p (struct cgraph_node *node)
+{
+ struct cgraph_edge *edge;
+
+ if (node->local.inline_summary.self_hot_insns > 0)
+ return true;
+
+ for (edge = node->callees; edge; edge = edge->next_callee)
+ if (cgraph_maybe_hot_edge_p (edge))
+ return true;
+
+ for (edge = node->callers; edge; edge = edge->next_caller)
+ if (cgraph_maybe_hot_edge_p (edge))
+ return true;
+
+ return false;
+}
+
#include "gt-cgraph.h"
diff --git a/gcc-4.4.3/gcc/cgraph.h b/gcc-4.4.3/gcc/cgraph.h
index 2df9d0821..f83ba05b2 100644
--- a/gcc-4.4.3/gcc/cgraph.h
+++ b/gcc-4.4.3/gcc/cgraph.h
@@ -111,8 +111,9 @@ struct cgraph_global_info GTY(())
/* Estimated size of the function after inlining. */
int insns;
- /* Estimated growth after inlining. INT_MIN if not computed. */
- int estimated_growth;
+ /* Estimated average per-callsite growth after inlining all calls to
+ this function. INT_MIN if not computed. */
+ int estimated_average_growth;
/* Set iff the function has been inlined at least once. */
bool inlined;
@@ -176,6 +177,8 @@ struct cgraph_node GTY((chain_next ("%h.next"), chain_prev ("%h.previous")))
/* Set when function must be output - it is externally visible
or its address is taken. */
unsigned needed : 1;
+ /* Set when the address of the function has been taken. */
+ unsigned address_taken : 1;
/* Set when decl is an abstract function pointed to by the
ABSTRACT_DECL_ORIGIN of a reachable function. */
unsigned abstract_and_needed : 1;
@@ -357,12 +360,15 @@ void cgraph_add_new_function (tree, bool);
void dump_vcg_cgraph (FILE *, int, bool);
+bool hot_function_p (struct cgraph_node *);
+
/* In cgraphunit.c */
void cgraph_finalize_function (tree, bool);
void cgraph_mark_if_needed (tree);
void cgraph_finalize_compilation_unit (void);
void cgraph_optimize (void);
void cgraph_mark_needed_node (struct cgraph_node *);
+void cgraph_mark_address_taken (struct cgraph_node *);
void cgraph_mark_reachable_node (struct cgraph_node *);
bool cgraph_inline_p (struct cgraph_edge *, const char **reason);
bool cgraph_preserve_function_body_p (tree);
@@ -536,6 +542,8 @@ void dump_hot_components (FILE *);
void verify_hot_components (void);
bool cgraph_gate_ipa_early_inlining (void);
+void cgraph_remove_pid (struct cgraph_node *);
+
/* Create a new static variable of type TYPE. */
tree add_new_static_var (tree type);
diff --git a/gcc-4.4.3/gcc/cgraphbuild.c b/gcc-4.4.3/gcc/cgraphbuild.c
index fb9c1611a..c412f5680 100644
--- a/gcc-4.4.3/gcc/cgraphbuild.c
+++ b/gcc-4.4.3/gcc/cgraphbuild.c
@@ -34,6 +34,7 @@ along with GCC; see the file COPYING3. If not see
#include "gcov-io.h"
#include "coverage.h"
#include "tree-pass.h"
+#include "tree-sample-profile.h"
/* Walk tree and record all calls and references to functions/variables.
Called via walk_tree: TP is pointer to tree to be examined. */
@@ -61,7 +62,10 @@ record_reference (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
functions reachable unconditionally. */
decl = TREE_OPERAND (*tp, 0);
if (TREE_CODE (decl) == FUNCTION_DECL)
- cgraph_mark_needed_node (cgraph_node (decl));
+ {
+ cgraph_mark_needed_node (cgraph_node (decl));
+ cgraph_mark_address_taken (cgraph_node (decl));
+ }
break;
default:
@@ -162,9 +166,31 @@ add_fake_indirect_call_edges (struct cgraph_node *node)
= get_coverage_counts_no_warn (DECL_STRUCT_FUNCTION (node->decl),
GCOV_COUNTER_ICALL_TOPNV, &n_counts);
- if (!ic_counts)
+ if (!ic_counts && !flag_sample_profile)
return;
+ /* For sample profile, we find the th indirect callees by its names. */
+ if (flag_sample_profile)
+ {
+ struct sample_indirect_call *ic =
+ sp_get_indirect_calls (cgraph_node_name (node));
+ if (!ic)
+ return;
+ for (i = 0; i < ic->num_values; i++)
+ {
+ struct cgraph_node *callee = find_func_by_name (ic->targets[i]);
+ if (callee)
+ {
+ struct cgraph_edge *e;
+ tree decl = callee->decl;
+ e = cgraph_create_edge (node, cgraph_real_node (decl), NULL,
+ ic->count[i], 0, 0);
+ e->indirect_call = 1;
+ }
+ }
+ return;
+ }
+
gcc_assert ((n_counts % GCOV_ICALL_TOPN_NCOUNTS) == 0);
/* After the early_inline_1 before value profile transformation,
diff --git a/gcc-4.4.3/gcc/common.opt b/gcc-4.4.3/gcc/common.opt
index 7f0f4e97d..3280c7330 100644
--- a/gcc-4.4.3/gcc/common.opt
+++ b/gcc-4.4.3/gcc/common.opt
@@ -249,6 +249,10 @@ Wuninitialized
Common Var(warn_uninitialized) Warning
Warn about uninitialized automatic variables
+Wmaybe-uninitialized
+Common Var(warn_maybe_uninitialized) Warning
+Warn about maybe uninitialized automatic variables
+
Wunreachable-code
Common Var(warn_notreached) Warning
Warn about code that will never be executed
@@ -421,6 +425,10 @@ fcaller-saves
Common Report Var(flag_caller_saves) Optimization
Save registers around function calls
+fcgraph-section
+Common Report Var(flag_cgraph_section) Init(0)
+Generate .note.callgraph.text sections listing callees and edge counts.
+
fcheck-data-deps
Common Report Var(flag_check_data_deps)
Compare the results of several data dependence analyzers.
@@ -515,6 +523,14 @@ fdwarf2-cfi-asm
Common Report Var(flag_dwarf2_cfi_asm) Init(HAVE_GAS_CFI_DIRECTIVE)
Enable CFI tables via GAS assembler directives.
+fprofile-reusedist
+Common Report Var(flag_profile_reusedist)
+Profile generation for memory reuse distance.
+
+foptimize-locality
+Common Report Var(flag_optimize_locality)
+Optimization based on improving memory reference locality.
+
fripa
Common Report Var(flag_dyn_ipa)
Perform Dynamic Inter-Procedural Analysis.
@@ -527,6 +543,12 @@ fripa-disallow-opt-mismatch
Common Report Var(flag_ripa_disallow_opt_mismatch)
Don't import an auxiliary module if the command line options mismatch with the primary module
+fripa-no-promote-always-inline-func
+Common Report Var(flag_ripa_no_promote_always_inline) Init(0)
+Don't promote always inline static functions assuming they
+will be inlined and no copy is needed.
+
+
fripa-verbose
Common Report Var(flag_ripa_verbose)
Enable verbose informational messages for LIPO compilation
@@ -535,6 +557,10 @@ fearly-inlining
Common Report Var(flag_early_inlining) Init(1) Optimization
Perform early inlining
+fearly-stack-alloc
+Common Report Var(flag_early_stack_alloc)
+Make stack coalescing decisions earlier
+
feliminate-dwarf2-dups
Common Report Var(flag_eliminate_dwarf2_dups)
Perform DWARF2 duplicate elimination
@@ -979,6 +1005,10 @@ fprofile-generate=
Common Joined RejectNegative
Enable common options for generating profile info for profile feedback directed optimizations, and set -fprofile-dir=
+fprofile-generate-sampling
+Common Var(flag_profile_generate_sampling)
+Turn on instrumentation sampling with -fprofile-generate with rate set by --param profile-generate-sampling-rate or environment variable GCOV_SAMPLING_RATE
+
fprofile-use
Common Var(flag_profile_use)
Enable common options for performing profile feedback directed optimizations
@@ -1044,6 +1074,14 @@ frounding-math
Common Report Var(flag_rounding_math) Optimization
Disable optimizations that assume default FP rounding behavior
+fpmu-profile-generate=
+Common Joined RejectNegative Var(flag_pmu_profile_generate)
+-fpmu-profile-generate=[load-latency] Generate pmu profile for cache misses. Currently only pfmon based load latency profiling is supported on Intel/PEBS and AMD/IBS platforms.
+
+fpmu-profile-use=
+Common Joined RejectNegative Var(flag_pmu_profile_use)
+-fpmu-profile-use=[load-latency] Use pmu profile data while optimizing. Currently only perfmon based load latency profiling is supported on Intel/PEBS and AMD/IBS platforms.
+
fsample-profile
Common Report Var(flag_sample_profile) Optimization
Use sample profile information for branch probabilities. The default sample
@@ -1479,6 +1517,15 @@ fvpt
Common Report Var(flag_value_profile_transformations) Optimization
Use expression value profiles in optimizations
+ffvpt
+Common Report Var(flag_float_value_profile_transformations) Optimization
+Enable floating point optimizations based on value profiles. Required
+both for profile generation and use.
+
+ffvpt-functions=
+Common Joined
+-ffvpt-functions=<function>[,<function>,...]|all List functions to optimize.
+
fweb
Common Report Var(flag_web) Init(2) Optimization
Construct webs and split unrelated uses of single variable
@@ -1487,6 +1534,10 @@ ftree-builtin-call-dce
Common Report Var(flag_tree_builtin_call_dce) Init(0) Optimization
Enable conditional dead code elimination for builtin calls
+fclone-hot-version-paths
+Common Report Var(flag_clone_hot_version_paths) Init(0)
+Enable cloning and hoisting of hot multiversioned paths
+
fwhole-program
Common Report Var(flag_whole_program) Init(0) Optimization
Perform whole program optimizations
diff --git a/gcc-4.4.3/gcc/config.gcc b/gcc-4.4.3/gcc/config.gcc
index 1a5315bce..4aed6f30e 100644
--- a/gcc-4.4.3/gcc/config.gcc
+++ b/gcc-4.4.3/gcc/config.gcc
@@ -300,7 +300,7 @@ i[34567]86-*-*)
pmmintrin.h tmmintrin.h ammintrin.h smmintrin.h
nmmintrin.h bmmintrin.h mmintrin-common.h
wmmintrin.h immintrin.h x86intrin.h avxintrin.h
- cross-stdarg.h"
+ cross-stdarg.h lwpintrin.h"
;;
x86_64-*-*)
cpu_type=i386
@@ -310,7 +310,7 @@ x86_64-*-*)
pmmintrin.h tmmintrin.h ammintrin.h smmintrin.h
nmmintrin.h bmmintrin.h mmintrin-common.h
wmmintrin.h immintrin.h x86intrin.h avxintrin.h
- cross-stdarg.h"
+ cross-stdarg.h lwpintrin.h"
need_64bit_hwint=yes
;;
ia64-*-*)
@@ -407,6 +407,9 @@ case ${target} in
;;
esac
+# Common C libraries.
+tm_defines="$tm_defines LIBC_GLIBC=1 LIBC_UCLIBC=2 LIBC_BIONIC=3"
+
# Common parts for widely ported systems.
case ${target} in
*-*-darwin*)
@@ -498,8 +501,6 @@ case ${target} in
*-*-gnu*)
tmake_file="$tmake_file t-gnu";;
esac
- # Common C libraries.
- tm_defines="$tm_defines LIBC_GLIBC=1 LIBC_UCLIBC=2 LIBC_BIONIC=3"
# glibc / uclibc / bionic switch.
# uclibc and bionic aren't usable for GNU/Hurd and neither for GNU/k*BSD.
case $target in
@@ -1117,7 +1118,7 @@ i[34567]86-*-linux* | i[34567]86-*-kfreebsd*-gnu | i[34567]86-*-knetbsd*-gnu | i
tmake_file="${tmake_file} i386/t-linux64"
need_64bit_hwint=yes
case X"${with_cpu}" in
- Xgeneric|Xcore2|Xnocona|Xx86-64|Xamdfam10|Xbarcelona|Xk8|Xopteron|Xathlon64|Xathlon-fx)
+ Xgeneric|Xatom|Xcore2|Xnocona|Xx86-64|Xamdfam10|Xbarcelona|Xk8|Xopteron|Xathlon64|Xathlon-fx)
;;
X)
if test x$with_cpu_64 = x; then
@@ -1126,7 +1127,7 @@ i[34567]86-*-linux* | i[34567]86-*-kfreebsd*-gnu | i[34567]86-*-knetbsd*-gnu | i
;;
*)
echo "Unsupported CPU used in --with-cpu=$with_cpu, supported values:" 1>&2
- echo "generic core2 nocona x86-64 amdfam10 barcelona k8 opteron athlon64 athlon-fx" 1>&2
+ echo "generic atom core2 nocona x86-64 amdfam10 barcelona k8 opteron athlon64 athlon-fx" 1>&2
exit 1
;;
esac
@@ -1237,7 +1238,7 @@ i[34567]86-*-solaris2*)
# libgcc/configure.ac instead.
need_64bit_hwint=yes
case X"${with_cpu}" in
- Xgeneric|Xcore2|Xnocona|Xx86-64|Xamdfam10|Xbarcelona|Xk8|Xopteron|Xathlon64|Xathlon-fx)
+ Xgeneric|Xatom|Xcore2|Xnocona|Xx86-64|Xamdfam10|Xbarcelona|Xk8|Xopteron|Xathlon64|Xathlon-fx)
;;
X)
if test x$with_cpu_64 = x; then
@@ -1246,7 +1247,7 @@ i[34567]86-*-solaris2*)
;;
*)
echo "Unsupported CPU used in --with-cpu=$with_cpu, supported values:" 1>&2
- echo "generic core2 nocona x86-64 amdfam10 barcelona k8 opteron athlon64 athlon-fx" 1>&2
+ echo "generic atom core2 nocona x86-64 amdfam10 barcelona k8 opteron athlon64 athlon-fx" 1>&2
exit 1
;;
esac
@@ -2624,6 +2625,27 @@ if test x$with_cpu = x ; then
esac
fi
+# Support --with-fpmath.
+if test x$with_fpmath != x; then
+ case ${target} in
+ i[34567]86-*-* | x86_64-*-*)
+ case ${with_fpmath} in
+ sse)
+ tm_file="${tm_file} i386/ssemath.h"
+ ;;
+ *)
+ echo "Invalid --with-fpmath=$with_fpmath" 1>&2
+ exit 1
+ ;;
+ esac
+ ;;
+ *)
+ echo "--with-fpmath isn't supported for $target." 1>&2
+ exit 1
+ ;;
+ esac
+fi
+
# Similarly for --with-schedule.
if test x$with_schedule = x; then
case ${target} in
@@ -2847,7 +2869,7 @@ case "${target}" in
esac
# OK
;;
- "" | amdfam10 | barcelona | k8 | opteron | athlon64 | athlon-fx | nocona | core2 | generic)
+ "" | amdfam10 | barcelona | k8 | opteron | athlon64 | athlon-fx | nocona | core2 | atom | generic)
# OK
;;
*)
diff --git a/gcc-4.4.3/gcc/config.in b/gcc-4.4.3/gcc/config.in
index 2c49621e8..a3a297ce9 100644
--- a/gcc-4.4.3/gcc/config.in
+++ b/gcc-4.4.3/gcc/config.in
@@ -46,6 +46,12 @@
#endif
+/* Define to 1 to enable crtbeginTS.o. */
+#ifndef USED_FOR_TARGET
+#undef ENABLE_CRTBEGINTS
+#endif
+
+
/* Define to 1 to specify that we are using the BID decimal floating point
format instead of DPD */
#ifndef USED_FOR_TARGET
@@ -65,6 +71,12 @@
#endif
+/* Define to 1 to enable esp. */
+#ifndef USED_FOR_TARGET
+#undef ENABLE_ESP
+#endif
+
+
/* Define to 1 to enable fixed-point arithmetic extension to C. */
#ifndef USED_FOR_TARGET
#undef ENABLE_FIXED_POINT
diff --git a/gcc-4.4.3/gcc/config/arm/arm-protos.h b/gcc-4.4.3/gcc/config/arm/arm-protos.h
index 8d03141e4..ee0a34393 100644
--- a/gcc-4.4.3/gcc/config/arm/arm-protos.h
+++ b/gcc-4.4.3/gcc/config/arm/arm-protos.h
@@ -154,13 +154,15 @@ extern bool arm_output_addr_const_extra (FILE *, rtx);
#if defined TREE_CODE
extern rtx arm_function_arg (CUMULATIVE_ARGS *, enum machine_mode, tree, int);
+extern void arm_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode,
+ tree, bool);
extern void arm_init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree);
extern bool arm_pad_arg_upward (enum machine_mode, const_tree);
extern bool arm_pad_reg_upward (enum machine_mode, tree, int);
extern bool arm_needs_doubleword_align (enum machine_mode, tree);
-extern rtx arm_function_value(const_tree, const_tree);
#endif
extern int arm_apply_result_size (void);
+extern rtx aapcs_libcall_value (enum machine_mode);
#endif /* RTX_CODE */
diff --git a/gcc-4.4.3/gcc/config/arm/arm.c b/gcc-4.4.3/gcc/config/arm/arm.c
index 2e2317b50..80bd3af3a 100644
--- a/gcc-4.4.3/gcc/config/arm/arm.c
+++ b/gcc-4.4.3/gcc/config/arm/arm.c
@@ -43,6 +43,7 @@
#include "optabs.h"
#include "toplev.h"
#include "recog.h"
+#include "cgraph.h"
#include "ggc.h"
#include "except.h"
#include "c-pragma.h"
@@ -54,6 +55,7 @@
#include "langhooks.h"
#include "df.h"
#include "libfuncs.h"
+#include "params.h"
/* Forward definitions of types. */
typedef struct minipool_node Mnode;
@@ -111,6 +113,7 @@ static unsigned long arm_compute_save_reg_mask (void);
static unsigned long arm_isr_value (tree);
static unsigned long arm_compute_func_type (void);
static tree arm_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
+static tree arm_handle_pcs_attribute (tree *, tree, tree, int, bool *);
static tree arm_handle_isr_attribute (tree *, tree, tree, int, bool *);
#if TARGET_DLLIMPORT_DECL_ATTRIBUTES
static tree arm_handle_notshared_attribute (tree *, tree, tree, int, bool *);
@@ -124,6 +127,10 @@ static int arm_adjust_cost (rtx, rtx, rtx, int);
static int count_insns_for_constant (HOST_WIDE_INT, int);
static int arm_get_strip_length (int);
static bool arm_function_ok_for_sibcall (tree, tree);
+static bool arm_return_in_memory (const_tree, const_tree);
+static rtx arm_function_value (const_tree, const_tree, bool);
+static rtx arm_libcall_value (enum machine_mode, rtx);
+
static void arm_internal_label (FILE *, const char *, unsigned long);
static void arm_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
tree);
@@ -150,6 +157,9 @@ static void emit_constant_insn (rtx cond, rtx pattern);
static rtx emit_set_insn (rtx, rtx);
static int arm_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
tree, bool);
+static rtx aapcs_allocate_return_reg (enum machine_mode, const_tree,
+ const_tree);
+static int aapcs_select_return_coproc (const_tree, const_tree);
#ifdef OBJECT_FORMAT_ELF
static void arm_elf_asm_constructor (rtx, int) ATTRIBUTE_UNUSED;
@@ -203,8 +213,8 @@ static rtx arm_pic_static_addr (rtx orig, rtx reg);
static rtx arm_get_pic_reg (void);
static void arm_clear_pic_reg (void);
static bool arm_can_simplify_got_access (int, int);
-static rtx arm_loaded_global_var (rtx, rtx *);
-static void arm_load_global_address (rtx, rtx, rtx, rtx);
+static rtx arm_loaded_global_var (rtx, rtx *, rtx *);
+static void arm_load_global_address (rtx, rtx, rtx, rtx, rtx);
/* Initialize the GCC target structure. */
@@ -264,6 +274,12 @@ static void arm_load_global_address (rtx, rtx, rtx, rtx);
#undef TARGET_FUNCTION_OK_FOR_SIBCALL
#define TARGET_FUNCTION_OK_FOR_SIBCALL arm_function_ok_for_sibcall
+#undef TARGET_FUNCTION_VALUE
+#define TARGET_FUNCTION_VALUE arm_function_value
+
+#undef TARGET_LIBCALL_VALUE
+#define TARGET_LIBCALL_VALUE arm_libcall_value
+
#undef TARGET_ASM_OUTPUT_MI_THUNK
#define TARGET_ASM_OUTPUT_MI_THUNK arm_output_mi_thunk
#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
@@ -621,6 +637,8 @@ static int after_arm_reorg = 0;
/* The maximum number of insns to be used when loading a constant. */
static int arm_constant_limit = 3;
+static enum arm_pcs arm_pcs_default;
+
/* For an explanation of these variables, see final_prescan_insn below. */
int arm_ccfsm_state;
/* arm_current_cc is also used for Thumb-2 cond_exec blocks. */
@@ -1536,9 +1554,6 @@ arm_override_options (void)
else
arm_float_abi = TARGET_DEFAULT_FLOAT_ABI;
- if (arm_float_abi == ARM_FLOAT_ABI_HARD && TARGET_VFP)
- sorry ("-mfloat-abi=hard and VFP");
-
/* FPA and iWMMXt are incompatible because the insn encodings overlap.
VFP and iWMMXt can theoretically coexist, but it's unlikely such silicon
will ever exist. GCC makes no attempt to support this combination. */
@@ -1553,6 +1568,28 @@ arm_override_options (void)
if (TARGET_SOFT_FLOAT)
arm_fpu_arch = FPUTYPE_NONE;
+ if (TARGET_AAPCS_BASED)
+ {
+ if (arm_abi == ARM_ABI_IWMMXT)
+ arm_pcs_default = ARM_PCS_AAPCS_IWMMXT;
+ else if (arm_float_abi == ARM_FLOAT_ABI_HARD
+ && TARGET_HARD_FLOAT
+ && TARGET_VFP)
+ arm_pcs_default = ARM_PCS_AAPCS_VFP;
+ else
+ arm_pcs_default = ARM_PCS_AAPCS;
+ }
+ else
+ {
+ if (arm_float_abi == ARM_FLOAT_ABI_HARD && TARGET_VFP)
+ sorry ("-mfloat-abi=hard and VFP");
+
+ if (arm_abi == ARM_ABI_APCS)
+ arm_pcs_default = ARM_PCS_APCS;
+ else
+ arm_pcs_default = ARM_PCS_ATPCS;
+ }
+
/* For arm2/3 there is no need to do any scheduling if there is only
a floating point emulator, or we are doing software floating-point. */
if ((TARGET_SOFT_FLOAT
@@ -1682,6 +1719,16 @@ arm_override_options (void)
max_insns_skipped = 3;
}
+ /* Hot/Cold partitioning is not currently supported, since we can't
+ handle literal pool placement in that case. */
+ if (flag_reorder_blocks_and_partition)
+ {
+ inform (input_location,
+ "-freorder-blocks-and-partition not supported on this architecture");
+ flag_reorder_blocks_and_partition = 0;
+ flag_reorder_blocks = 1;
+ }
+
/* Ideally we would want to use CFI directives to generate
debug info. However this also creates the .eh_frame
section, so disable them until GAS can handle
@@ -1689,6 +1736,21 @@ arm_override_options (void)
if (TARGET_AAPCS_BASED)
flag_dwarf2_cfi_asm = 0;
+ if (!PARAM_SET_P (PARAM_INLINE_CALL_COST))
+ set_param_value ("inline-call-cost", 2);
+
+ if (!PARAM_SET_P (PARAM_INLINE_FUNCTION_SIZE_ADJUSTMENT))
+ set_param_value ("inline-function-size-adjustment", 3);
+
+ if (!PARAM_SET_P (PARAM_INLINE_ADDRESS_TAKEN_FUNCTION_EMIT_PROBABILITY))
+ set_param_value ("inline-address-taken-function-emit-probability", 100);
+
+ if (!PARAM_SET_P (PARAM_INLINE_ADDRESS_NOT_TAKEN_FUNCTION_EMIT_PROBABILITY))
+ set_param_value ("inline-address-not-taken-function-emit-probability", 100);
+
+ if (!PARAM_SET_P (PARAM_INLINE_PRIORITY_THRESHOLD))
+ set_param_value ("inline-priority-threshold", 0);
+
/* Register global variables with the garbage collector. */
arm_add_gc_roots ();
}
@@ -2911,14 +2973,19 @@ arm_canonicalize_comparison (enum rtx_code code, enum machine_mode mode,
/* Define how to find the value returned by a function. */
-rtx
-arm_function_value(const_tree type, const_tree func ATTRIBUTE_UNUSED)
+static rtx
+arm_function_value(const_tree type, const_tree func,
+ bool outgoing ATTRIBUTE_UNUSED)
{
enum machine_mode mode;
int unsignedp ATTRIBUTE_UNUSED;
rtx r ATTRIBUTE_UNUSED;
mode = TYPE_MODE (type);
+
+ if (TARGET_AAPCS_BASED)
+ return aapcs_allocate_return_reg (mode, type, func);
+
/* Promote integer types. */
if (INTEGRAL_TYPE_P (type))
PROMOTE_FUNCTION_MODE (mode, unsignedp, type);
@@ -2935,7 +3002,87 @@ arm_function_value(const_tree type, const_tree func ATTRIBUTE_UNUSED)
}
}
- return LIBCALL_VALUE(mode);
+ return LIBCALL_VALUE (mode);
+}
+
+static int
+libcall_eq (const void *p1, const void *p2)
+{
+ return rtx_equal_p ((const_rtx) p1, (const_rtx) p2);
+}
+
+static hashval_t
+libcall_hash (const void *p1)
+{
+ return hash_rtx ((const_rtx) p1, VOIDmode, NULL, NULL, FALSE);
+}
+
+static void
+add_libcall (htab_t htab, rtx libcall)
+{
+ *htab_find_slot (htab, libcall, INSERT) = libcall;
+}
+
+static bool
+arm_libcall_uses_aapcs_base (rtx libcall)
+{
+ static bool init_done = false;
+ static htab_t libcall_htab;
+
+ if (!init_done)
+ {
+ init_done = true;
+
+ libcall_htab = htab_create (31, libcall_hash, libcall_eq,
+ NULL);
+ add_libcall (libcall_htab,
+ convert_optab_libfunc (sfloat_optab, SFmode, SImode));
+ add_libcall (libcall_htab,
+ convert_optab_libfunc (sfloat_optab, DFmode, SImode));
+ add_libcall (libcall_htab,
+ convert_optab_libfunc (sfloat_optab, SFmode, DImode));
+ add_libcall (libcall_htab,
+ convert_optab_libfunc (sfloat_optab, DFmode, DImode));
+
+ add_libcall (libcall_htab,
+ convert_optab_libfunc (ufloat_optab, SFmode, SImode));
+ add_libcall (libcall_htab,
+ convert_optab_libfunc (ufloat_optab, DFmode, SImode));
+ add_libcall (libcall_htab,
+ convert_optab_libfunc (ufloat_optab, SFmode, DImode));
+ add_libcall (libcall_htab,
+ convert_optab_libfunc (ufloat_optab, DFmode, DImode));
+
+ /* add_libcall (libcall_htab,
+ convert_optab_libfunc (sext_optab, SFmode, HFmode));
+ add_libcall (libcall_htab,
+ convert_optab_libfunc (trunc_optab, HFmode, SFmode)); */
+ add_libcall (libcall_htab,
+ convert_optab_libfunc (sfix_optab, DImode, DFmode));
+ add_libcall (libcall_htab,
+ convert_optab_libfunc (ufix_optab, DImode, DFmode));
+ add_libcall (libcall_htab,
+ convert_optab_libfunc (sfix_optab, DImode, SFmode));
+ add_libcall (libcall_htab,
+ convert_optab_libfunc (ufix_optab, DImode, SFmode));
+ }
+
+ return libcall && htab_find (libcall_htab, libcall) != NULL;
+}
+
+rtx
+arm_libcall_value (enum machine_mode mode, rtx libcall)
+{
+ if (TARGET_AAPCS_BASED && arm_pcs_default != ARM_PCS_AAPCS
+ && GET_MODE_CLASS (mode) == MODE_FLOAT)
+ {
+ /* The following libcalls return their result in integer registers,
+ even though they return a floating point value. */
+ if (arm_libcall_uses_aapcs_base (libcall))
+ return gen_rtx_REG (mode, ARG_REGISTER(1));
+ }
+
+ return LIBCALL_VALUE (mode);
}
/* Determine the amount of memory needed to store the possible return
@@ -2945,10 +3092,12 @@ arm_apply_result_size (void)
{
int size = 16;
- if (TARGET_ARM)
+ if (TARGET_32BIT)
{
if (TARGET_HARD_FLOAT_ABI)
{
+ if (TARGET_VFP)
+ size += 32;
if (TARGET_FPA)
size += 12;
if (TARGET_MAVERICK)
@@ -2961,27 +3110,56 @@ arm_apply_result_size (void)
return size;
}
-/* Decide whether a type should be returned in memory (true)
- or in a register (false). This is called as the target hook
- TARGET_RETURN_IN_MEMORY. */
+/* Decide whether TYPE should be returned in memory (true)
+ or in a register (false). FNTYPE is the type of the function making
+ the call. */
static bool
-arm_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
+arm_return_in_memory (const_tree type, const_tree fntype)
{
HOST_WIDE_INT size;
- size = int_size_in_bytes (type);
+ size = int_size_in_bytes (type); /* Negative if not fixed size. */
+
+ if (TARGET_AAPCS_BASED)
+ {
+ /* Simple, non-aggregate types (ie not including vectors and
+ complex) are always returned in a register (or registers).
+ We don't care about which register here, so we can short-cut
+ some of the detail. */
+ if (!AGGREGATE_TYPE_P (type)
+ && TREE_CODE (type) != VECTOR_TYPE
+ && TREE_CODE (type) != COMPLEX_TYPE)
+ return false;
+
+ /* Any return value that is no larger than one word can be
+ returned in r0. */
+ if (((unsigned HOST_WIDE_INT) size) <= UNITS_PER_WORD)
+ return false;
+
+ /* Check any available co-processors to see if they accept the
+ type as a register candidate (VFP, for example, can return
+ some aggregates in consecutive registers). These aren't
+ available if the call is variadic. */
+ if (aapcs_select_return_coproc (type, fntype) >= 0)
+ return false;
+
+ /* Vector values should be returned using ARM registers, not
+ memory (unless they're over 16 bytes, which will break since
+ we only have four call-clobbered registers to play with). */
+ if (TREE_CODE (type) == VECTOR_TYPE)
+ return (size < 0 || size > (4 * UNITS_PER_WORD));
+
+ /* The rest go in memory. */
+ return true;
+ }
- /* Vector values should be returned using ARM registers, not memory (unless
- they're over 16 bytes, which will break since we only have four
- call-clobbered registers to play with). */
if (TREE_CODE (type) == VECTOR_TYPE)
return (size < 0 || size > (4 * UNITS_PER_WORD));
if (!AGGREGATE_TYPE_P (type) &&
- !(TARGET_AAPCS_BASED && TREE_CODE (type) == COMPLEX_TYPE))
- /* All simple types are returned in registers.
- For AAPCS, complex types are treated the same as aggregates. */
- return 0;
+ (TREE_CODE (type) != VECTOR_TYPE))
+ /* All simple types are returned in registers. */
+ return false;
if (arm_abi != ARM_ABI_APCS)
{
@@ -2998,7 +3176,7 @@ arm_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
the aggregate is either huge or of variable size, and in either case
we will want to return it via memory and not in a register. */
if (size < 0 || size > UNITS_PER_WORD)
- return 1;
+ return true;
if (TREE_CODE (type) == RECORD_TYPE)
{
@@ -3018,18 +3196,18 @@ arm_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
continue;
if (field == NULL)
- return 0; /* An empty structure. Allowed by an extension to ANSI C. */
+ return false; /* An empty structure. Allowed by an extension to ANSI C. */
/* Check that the first field is valid for returning in a register. */
/* ... Floats are not allowed */
if (FLOAT_TYPE_P (TREE_TYPE (field)))
- return 1;
+ return true;
/* ... Aggregates that are not themselves valid for returning in
a register are not allowed. */
if (arm_return_in_memory (TREE_TYPE (field), NULL_TREE))
- return 1;
+ return true;
/* Now check the remaining fields, if any. Only bitfields are allowed,
since they are not addressable. */
@@ -3041,10 +3219,10 @@ arm_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
continue;
if (!DECL_BIT_FIELD_TYPE (field))
- return 1;
+ return true;
}
- return 0;
+ return false;
}
if (TREE_CODE (type) == UNION_TYPE)
@@ -3061,18 +3239,18 @@ arm_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
continue;
if (FLOAT_TYPE_P (TREE_TYPE (field)))
- return 1;
+ return true;
if (arm_return_in_memory (TREE_TYPE (field), NULL_TREE))
- return 1;
+ return true;
}
- return 0;
+ return false;
}
#endif /* not ARM_WINCE */
/* Return all other types in memory. */
- return 1;
+ return false;
}
/* Indicate whether or not words of a double are in big-endian order. */
@@ -3097,14 +3275,752 @@ arm_float_words_big_endian (void)
return 1;
}
+const struct pcs_attribute_arg
+{
+ const char *arg;
+ enum arm_pcs value;
+} pcs_attribute_args[] =
+ {
+ {"aapcs", ARM_PCS_AAPCS},
+ {"aapcs-vfp", ARM_PCS_AAPCS_VFP},
+#if 0
+ /* We could recognize these, but changes would be needed elsewhere
+ * to implement them. */
+ {"aapcs-iwmmxt", ARM_PCS_AAPCS_IWMMXT},
+ {"atpcs", ARM_PCS_ATPCS},
+ {"apcs", ARM_PCS_APCS},
+#endif
+ {NULL, ARM_PCS_UNKNOWN}
+ };
+
+static enum arm_pcs
+arm_pcs_from_attribute (tree attr)
+{
+ const struct pcs_attribute_arg *ptr;
+ const char *arg;
+
+ /* Get the value of the argument. */
+ if (TREE_VALUE (attr) == NULL_TREE
+ || TREE_CODE (TREE_VALUE (attr)) != STRING_CST)
+ return ARM_PCS_UNKNOWN;
+
+ arg = TREE_STRING_POINTER (TREE_VALUE (attr));
+
+ /* Check it against the list of known arguments. */
+ for (ptr = pcs_attribute_args; ptr->arg != NULL; ptr++)
+ if (streq (arg, ptr->arg))
+ return ptr->value;
+
+ /* An unrecognized interrupt type. */
+ return ARM_PCS_UNKNOWN;
+}
+
+/* Get the PCS variant to use for this call. TYPE is the function's type
+ specification, DECL is the specific declartion. DECL may be null if
+ the call could be indirect or if this is a library call. */
+static enum arm_pcs
+arm_get_pcs_model (const_tree type, const_tree decl)
+{
+ bool user_convention = false;
+ enum arm_pcs user_pcs = arm_pcs_default;
+ tree attr;
+
+ gcc_assert (type);
+
+ attr = lookup_attribute ("pcs", TYPE_ATTRIBUTES (type));
+ if (attr)
+ {
+ user_pcs = arm_pcs_from_attribute (TREE_VALUE (attr));
+ user_convention = true;
+ }
+
+ if (TARGET_AAPCS_BASED)
+ {
+ /* Detect varargs functions. These always use the base rules
+ (no argument is ever a candidate for a co-processor
+ register). */
+ bool base_rules = (TYPE_ARG_TYPES (type) != 0
+ && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (type)))
+ != void_type_node));
+
+ if (user_convention)
+ {
+ if (user_pcs > ARM_PCS_AAPCS_LOCAL)
+ sorry ("Non-AAPCS derived PCS variant");
+ else if (base_rules && user_pcs != ARM_PCS_AAPCS)
+ error ("Variadic functions must use the base AAPCS variant");
+ }
+
+ if (base_rules)
+ return ARM_PCS_AAPCS;
+ else if (user_convention)
+ return user_pcs;
+ else if (decl && flag_unit_at_a_time)
+ {
+ /* Local functions never leak outside this compilation unit,
+ so we are free to use whatever conventions are
+ appropriate. */
+ /* FIXME: remove CONST_CAST_TREE when cgraph is constified. */
+ struct cgraph_local_info *i = cgraph_local_info (CONST_CAST_TREE(decl));
+ if (i && i->local)
+ return ARM_PCS_AAPCS_LOCAL;
+ }
+ }
+ else if (user_convention && user_pcs != arm_pcs_default)
+ sorry ("PCS variant");
+
+ /* For everything else we use the target's default. */
+ return arm_pcs_default;
+}
+
+
+static void
+aapcs_vfp_cum_init (CUMULATIVE_ARGS *pcum ATTRIBUTE_UNUSED,
+ const_tree fntype ATTRIBUTE_UNUSED,
+ rtx libcall ATTRIBUTE_UNUSED,
+ const_tree fndecl ATTRIBUTE_UNUSED)
+{
+ /* Record the unallocated VFP registers. */
+ pcum->aapcs_vfp_regs_free = (1 << NUM_VFP_ARG_REGS) - 1;
+ pcum->aapcs_vfp_reg_alloc = 0;
+}
+
+/* Walk down the type tree of TYPE counting consecutive base elements.
+ If *MODEP is VOIDmode, then set it to the first valid floating point
+ type. If a non-floating point type is found, or if a floating point
+ type that doesn't match a non-VOIDmode *MODEP is found, then return -1,
+ otherwise return the count in the sub-tree. */
+static int
+aapcs_vfp_sub_candidate (const_tree type, enum machine_mode *modep)
+{
+ enum machine_mode mode;
+ HOST_WIDE_INT size;
+
+ switch (TREE_CODE (type))
+ {
+ case REAL_TYPE:
+ mode = TYPE_MODE (type);
+ if (mode != DFmode && mode != SFmode)
+ return -1;
+
+ if (*modep == VOIDmode)
+ *modep = mode;
+
+ if (*modep == mode)
+ return 1;
+
+ break;
+
+ case COMPLEX_TYPE:
+ mode = TYPE_MODE (TREE_TYPE (type));
+ if (mode != DFmode && mode != SFmode)
+ return -1;
+
+ if (*modep == VOIDmode)
+ *modep = mode;
+
+ if (*modep == mode)
+ return 2;
+
+ break;
+
+ case VECTOR_TYPE:
+ /* Use V2SImode and V4SImode as representatives of all 64-bit
+ and 128-bit vector types, whether or not those modes are
+ supported with the present options. */
+ size = int_size_in_bytes (type);
+ switch (size)
+ {
+ case 8:
+ mode = V2SImode;
+ break;
+ case 16:
+ mode = V4SImode;
+ break;
+ default:
+ return -1;
+ }
+
+ if (*modep == VOIDmode)
+ *modep = mode;
+
+ /* Vector modes are considered to be opaque: two vectors are
+ equivalent for the purposes of being homogeneous aggregates
+ if they are the same size. */
+ if (*modep == mode)
+ return 1;
+
+ break;
+
+ case ARRAY_TYPE:
+ {
+ int count;
+ tree index = TYPE_DOMAIN (type);
+
+ /* Can't handle incomplete types. */
+ if (!COMPLETE_TYPE_P(type))
+ return -1;
+
+ count = aapcs_vfp_sub_candidate (TREE_TYPE (type), modep);
+ if (count == -1
+ || !index
+ || !TYPE_MAX_VALUE (index)
+ || !host_integerp (TYPE_MAX_VALUE (index), 1)
+ || !TYPE_MIN_VALUE (index)
+ || !host_integerp (TYPE_MIN_VALUE (index), 1)
+ || count < 0)
+ return -1;
+
+ count *= (1 + tree_low_cst (TYPE_MAX_VALUE (index), 1)
+ - tree_low_cst (TYPE_MIN_VALUE (index), 1));
+
+ /* There must be no padding. */
+ if (!host_integerp (TYPE_SIZE (type), 1)
+ || (tree_low_cst (TYPE_SIZE (type), 1)
+ != count * GET_MODE_BITSIZE (*modep)))
+ return -1;
+
+ return count;
+ }
+
+ case RECORD_TYPE:
+ {
+ int count = 0;
+ int sub_count;
+ tree field;
+
+ /* Can't handle incomplete types. */
+ if (!COMPLETE_TYPE_P(type))
+ return -1;
+
+ for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
+ {
+ if (TREE_CODE (field) != FIELD_DECL)
+ continue;
+
+ sub_count = aapcs_vfp_sub_candidate (TREE_TYPE (field), modep);
+ if (sub_count < 0)
+ return -1;
+ count += sub_count;
+ }
+
+ /* There must be no padding. */
+ if (!host_integerp (TYPE_SIZE (type), 1)
+ || (tree_low_cst (TYPE_SIZE (type), 1)
+ != count * GET_MODE_BITSIZE (*modep)))
+ return -1;
+
+ return count;
+ }
+
+ case UNION_TYPE:
+ case QUAL_UNION_TYPE:
+ {
+ /* These aren't very interesting except in a degenerate case. */
+ int count = 0;
+ int sub_count;
+ tree field;
+
+ /* Can't handle incomplete types. */
+ if (!COMPLETE_TYPE_P(type))
+ return -1;
+
+ for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
+ {
+ if (TREE_CODE (field) != FIELD_DECL)
+ continue;
+
+ sub_count = aapcs_vfp_sub_candidate (TREE_TYPE (field), modep);
+ if (sub_count < 0)
+ return -1;
+ count = count > sub_count ? count : sub_count;
+ }
+
+ /* There must be no padding. */
+ if (!host_integerp (TYPE_SIZE (type), 1)
+ || (tree_low_cst (TYPE_SIZE (type), 1)
+ != count * GET_MODE_BITSIZE (*modep)))
+ return -1;
+
+ return count;
+ }
+
+ default:
+ break;
+ }
+
+ return -1;
+}
+
+static bool
+aapcs_vfp_is_call_or_return_candidate (enum machine_mode mode, const_tree type,
+ int *base_mode,
+ int *count)
+{
+ if (GET_MODE_CLASS (mode) == MODE_FLOAT
+ || GET_MODE_CLASS (mode) == MODE_VECTOR_INT
+ || GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT)
+ {
+ *count = 1;
+ *base_mode = mode;
+ return true;
+ }
+ else if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
+ {
+ *count = 2;
+ *base_mode = (mode == DCmode ? DFmode : SFmode);
+ return true;
+ }
+ else if (type && (mode == BLKmode || TREE_CODE (type) == VECTOR_TYPE))
+ {
+ enum machine_mode aggregate_mode = VOIDmode;
+ int ag_count = aapcs_vfp_sub_candidate (type, &aggregate_mode);
+
+ if (ag_count > 0 && ag_count <= 4)
+ {
+ *count = ag_count;
+ *base_mode = aggregate_mode;
+ return true;
+ }
+ }
+ return false;
+}
+
+static bool
+aapcs_vfp_is_return_candidate (enum arm_pcs pcs_variant,
+ enum machine_mode mode, const_tree type)
+{
+ int count ATTRIBUTE_UNUSED;
+ int ag_mode ATTRIBUTE_UNUSED;
+
+ if (!(pcs_variant == ARM_PCS_AAPCS_VFP
+ || (pcs_variant == ARM_PCS_AAPCS_LOCAL
+ && TARGET_32BIT && TARGET_VFP && TARGET_HARD_FLOAT)))
+ return false;
+ return aapcs_vfp_is_call_or_return_candidate (mode, type, &ag_mode, &count);
+}
+
+static bool
+aapcs_vfp_is_call_candidate (CUMULATIVE_ARGS *pcum, enum machine_mode mode,
+ const_tree type)
+{
+ if (!(pcum->pcs_variant == ARM_PCS_AAPCS_VFP
+ || (pcum->pcs_variant == ARM_PCS_AAPCS_LOCAL
+ && TARGET_32BIT && TARGET_VFP && TARGET_HARD_FLOAT)))
+ return false;
+ return aapcs_vfp_is_call_or_return_candidate (mode, type,
+ &pcum->aapcs_vfp_rmode,
+ &pcum->aapcs_vfp_rcount);
+}
+
+static bool
+aapcs_vfp_allocate (CUMULATIVE_ARGS *pcum, enum machine_mode mode,
+ const_tree type ATTRIBUTE_UNUSED)
+{
+ int shift = GET_MODE_SIZE (pcum->aapcs_vfp_rmode) / GET_MODE_SIZE (SFmode);
+ unsigned mask = (1 << (shift * pcum->aapcs_vfp_rcount)) - 1;
+ int regno;
+
+ for (regno = 0; regno < NUM_VFP_ARG_REGS; regno += shift)
+ if (((pcum->aapcs_vfp_regs_free >> regno) & mask) == mask)
+ {
+ pcum->aapcs_vfp_reg_alloc = mask << regno;
+ if (mode == BLKmode || (mode == TImode && !TARGET_NEON))
+ {
+ int i;
+ int rcount = pcum->aapcs_vfp_rcount;
+ int rshift = shift;
+ enum machine_mode rmode = pcum->aapcs_vfp_rmode;
+ rtx par;
+ if (!TARGET_NEON)
+ {
+ /* Avoid using unsupported vector modes. */
+ if (rmode == V2SImode)
+ rmode = DImode;
+ else if (rmode == V4SImode)
+ {
+ rmode = DImode;
+ rcount *= 2;
+ rshift /= 2;
+ }
+ }
+ par = gen_rtx_PARALLEL (mode, rtvec_alloc (rcount));
+ for (i = 0; i < rcount; i++)
+ {
+ rtx tmp = gen_rtx_REG (rmode,
+ FIRST_VFP_REGNUM + regno + i * rshift);
+ tmp = gen_rtx_EXPR_LIST
+ (VOIDmode, tmp,
+ GEN_INT (i * GET_MODE_SIZE (rmode)));
+ XVECEXP (par, 0, i) = tmp;
+ }
+
+ pcum->aapcs_reg = par;
+ }
+ else
+ pcum->aapcs_reg = gen_rtx_REG (mode, FIRST_VFP_REGNUM + regno);
+ return true;
+ }
+ return false;
+}
+
+static rtx
+aapcs_vfp_allocate_return_reg (enum arm_pcs pcs_variant ATTRIBUTE_UNUSED,
+ enum machine_mode mode,
+ const_tree type ATTRIBUTE_UNUSED)
+{
+ if (!(pcs_variant == ARM_PCS_AAPCS_VFP
+ || (pcs_variant == ARM_PCS_AAPCS_LOCAL
+ && TARGET_32BIT && TARGET_VFP && TARGET_HARD_FLOAT)))
+ return false;
+ if (mode == BLKmode || (mode == TImode && !TARGET_NEON))
+ {
+ int count;
+ int ag_mode;
+ int i;
+ rtx par;
+ int shift;
+
+ aapcs_vfp_is_call_or_return_candidate (mode, type, &ag_mode, &count);
+
+ if (!TARGET_NEON)
+ {
+ if (ag_mode == V2SImode)
+ ag_mode = DImode;
+ else if (ag_mode == V4SImode)
+ {
+ ag_mode = DImode;
+ count *= 2;
+ }
+ }
+ shift = GET_MODE_SIZE(ag_mode) / GET_MODE_SIZE(SFmode);
+ par = gen_rtx_PARALLEL (mode, rtvec_alloc (count));
+ for (i = 0; i < count; i++)
+ {
+ rtx tmp = gen_rtx_REG (ag_mode, FIRST_VFP_REGNUM + i * shift);
+ tmp = gen_rtx_EXPR_LIST (VOIDmode, tmp,
+ GEN_INT (i * GET_MODE_SIZE (ag_mode)));
+ XVECEXP (par, 0, i) = tmp;
+ }
+
+ return par;
+ }
+
+ return gen_rtx_REG (mode, FIRST_VFP_REGNUM);
+}
+
+static void
+aapcs_vfp_advance (CUMULATIVE_ARGS *pcum ATTRIBUTE_UNUSED,
+ enum machine_mode mode ATTRIBUTE_UNUSED,
+ const_tree type ATTRIBUTE_UNUSED)
+{
+ pcum->aapcs_vfp_regs_free &= ~pcum->aapcs_vfp_reg_alloc;
+ pcum->aapcs_vfp_reg_alloc = 0;
+ return;
+}
+
+#define AAPCS_CP(X) \
+ { \
+ aapcs_ ## X ## _cum_init, \
+ aapcs_ ## X ## _is_call_candidate, \
+ aapcs_ ## X ## _allocate, \
+ aapcs_ ## X ## _is_return_candidate, \
+ aapcs_ ## X ## _allocate_return_reg, \
+ aapcs_ ## X ## _advance \
+ }
+
+/* Table of co-processors that can be used to pass arguments in
+ registers. Idealy no arugment should be a candidate for more than
+ one co-processor table entry, but the table is processed in order
+ and stops after the first match. If that entry then fails to put
+ the argument into a co-processor register, the argument will go on
+ the stack. */
+static struct
+{
+ /* Initialize co-processor related state in CUMULATIVE_ARGS structure. */
+ void (*cum_init) (CUMULATIVE_ARGS *, const_tree, rtx, const_tree);
+
+ /* Return true if an argument of mode MODE (or type TYPE if MODE is
+ BLKmode) is a candidate for this co-processor's registers; this
+ function should ignore any position-dependent state in
+ CUMULATIVE_ARGS and only use call-type dependent information. */
+ bool (*is_call_candidate) (CUMULATIVE_ARGS *, enum machine_mode, const_tree);
+
+ /* Return true if the argument does get a co-processor register; it
+ should set aapcs_reg to an RTX of the register allocated as is
+ required for a return from FUNCTION_ARG. */
+ bool (*allocate) (CUMULATIVE_ARGS *, enum machine_mode, const_tree);
+
+ /* Return true if a result of mode MODE (or type TYPE if MODE is
+ BLKmode) is can be returned in this co-processor's registers. */
+ bool (*is_return_candidate) (enum arm_pcs, enum machine_mode, const_tree);
+
+ /* Allocate and return an RTX element to hold the return type of a
+ call, this routine must not fail and will only be called if
+ is_return_candidate returned true with the same parameters. */
+ rtx (*allocate_return_reg) (enum arm_pcs, enum machine_mode, const_tree);
+
+ /* Finish processing this argument and prepare to start processing
+ the next one. */
+ void (*advance) (CUMULATIVE_ARGS *, enum machine_mode, const_tree);
+} aapcs_cp_arg_layout[ARM_NUM_COPROC_SLOTS] =
+ {
+ AAPCS_CP(vfp)
+ };
+
+#undef AAPCS_CP
+
+static int
+aapcs_select_call_coproc (CUMULATIVE_ARGS *pcum, enum machine_mode mode,
+ tree type)
+{
+ int i;
+
+ for (i = 0; i < ARM_NUM_COPROC_SLOTS; i++)
+ if (aapcs_cp_arg_layout[i].is_call_candidate (pcum, mode, type))
+ return i;
+
+ return -1;
+}
+
+static int
+aapcs_select_return_coproc (const_tree type, const_tree fntype)
+{
+ /* We aren't passed a decl, so we can't check that a call is local.
+ However, it isn't clear that that would be a win anyway, since it
+ might limit some tail-calling opportunities. */
+ enum arm_pcs pcs_variant;
+
+ if (fntype)
+ {
+ const_tree fndecl = NULL_TREE;
+ if (TREE_CODE (fntype) == FUNCTION_DECL)
+ {
+ fndecl = fntype;
+ fntype = TREE_TYPE (fntype);
+ }
+
+ pcs_variant = arm_get_pcs_model (fntype, fndecl);
+ }
+ else
+ pcs_variant = arm_pcs_default;
+
+ if (pcs_variant != ARM_PCS_AAPCS)
+ {
+ int i;
+
+ for (i = 0; i < ARM_NUM_COPROC_SLOTS; i++)
+ if (aapcs_cp_arg_layout[i].is_return_candidate (pcs_variant,
+ TYPE_MODE (type),
+ type))
+ return i;
+ }
+ return -1;
+}
+
+static rtx
+aapcs_allocate_return_reg (enum machine_mode mode, const_tree type,
+ const_tree fntype)
+{
+ /* We aren't passed a decl, so we can't check that a call is local.
+ However, it isn't clear that that would be a win anyway, since it
+ might limit some tail-calling opportunities. */
+ enum arm_pcs pcs_variant;
+ int unsignedp ATTRIBUTE_UNUSED;
+
+ if (fntype)
+ {
+ const_tree fndecl = NULL_TREE;
+
+ if (TREE_CODE (fntype) == FUNCTION_DECL)
+ {
+ fndecl = fntype;
+ fntype = TREE_TYPE (fntype);
+ }
+
+ pcs_variant = arm_get_pcs_model (fntype, fndecl);
+ }
+ else
+ pcs_variant = arm_pcs_default;
+
+ /* Promote integer types. */
+ if (type && INTEGRAL_TYPE_P (type))
+ PROMOTE_FUNCTION_MODE (mode, unsignedp, type);
+
+ if (pcs_variant != ARM_PCS_AAPCS)
+ {
+ int i;
+
+ for (i = 0; i < ARM_NUM_COPROC_SLOTS; i++)
+ if (aapcs_cp_arg_layout[i].is_return_candidate (pcs_variant, mode,
+ type))
+ return aapcs_cp_arg_layout[i].allocate_return_reg (pcs_variant,
+ mode, type);
+ }
+
+ /* Promotes small structs returned in a register to full-word size
+ for big-endian AAPCS. */
+ if (type && arm_return_in_msb (type))
+ {
+ HOST_WIDE_INT size = int_size_in_bytes (type);
+ if (size % UNITS_PER_WORD != 0)
+ {
+ size += UNITS_PER_WORD - size % UNITS_PER_WORD;
+ mode = mode_for_size (size * BITS_PER_UNIT, MODE_INT, 0);
+ }
+ }
+
+ return gen_rtx_REG (mode, R0_REGNUM);
+}
+
+rtx
+aapcs_libcall_value (enum machine_mode mode)
+{
+ return aapcs_allocate_return_reg (mode, NULL_TREE, NULL_TREE);
+}
+
+/* Lay out a function argument using the AAPCS rules. The rule
+ numbers referred to here are those in the AAPCS. */
+static void
+aapcs_layout_arg (CUMULATIVE_ARGS *pcum, enum machine_mode mode,
+ tree type, int named)
+{
+ int nregs, nregs2;
+ int ncrn;
+
+ /* We only need to do this once per argument. */
+ if (pcum->aapcs_arg_processed)
+ return;
+
+ pcum->aapcs_arg_processed = true;
+
+ /* Special case: if named is false then we are handling an incoming
+ anonymous argument which is on the stack. */
+ if (!named)
+ return;
+
+ /* Is this a potential co-processor register candidate? */
+ if (pcum->pcs_variant != ARM_PCS_AAPCS)
+ {
+ int slot = aapcs_select_call_coproc (pcum, mode, type);
+ pcum->aapcs_cprc_slot = slot;
+
+ /* We don't have to apply any of the rules from part B of the
+ preparation phase, these are handled elsewhere in the
+ compiler. */
+
+ if (slot >= 0)
+ {
+ /* A Co-processor register candidate goes either in its own
+ class of registers or on the stack. */
+ if (!pcum->aapcs_cprc_failed[slot])
+ {
+ /* C1.cp - Try to allocate the argument to co-processor
+ registers. */
+ if (aapcs_cp_arg_layout[slot].allocate (pcum, mode, type))
+ return;
+
+ /* C2.cp - Put the argument on the stack and note that we
+ can't assign any more candidates in this slot. We also
+ need to note that we have allocated stack space, so that
+ we won't later try to split a non-cprc candidate between
+ core registers and the stack. */
+ pcum->aapcs_cprc_failed[slot] = true;
+ pcum->can_split = false;
+ }
+
+ /* We didn't get a register, so this argument goes on the
+ stack. */
+ gcc_assert (pcum->can_split == false);
+ return;
+ }
+ }
+
+ /* C3 - For double-word aligned arguments, round the NCRN up to the
+ next even number. */
+ ncrn = pcum->aapcs_ncrn;
+ if ((ncrn & 1) && arm_needs_doubleword_align (mode, type))
+ ncrn++;
+
+ nregs = ARM_NUM_REGS2(mode, type);
+
+ /* Sigh, this test should really assert that nregs > 0, but a GCC
+ extension allows empty structs and then gives them empty size; it
+ then allows such a structure to be passed by value. For some of
+ the code below we have to pretend that such an argument has
+ non-zero size so that we 'locate' it correctly either in
+ registers or on the stack. */
+ gcc_assert (nregs >= 0);
+
+ nregs2 = nregs ? nregs : 1;
+
+ /* C4 - Argument fits entirely in core registers. */
+ if (ncrn + nregs2 <= NUM_ARG_REGS)
+ {
+ pcum->aapcs_reg = gen_rtx_REG (mode, ncrn);
+ pcum->aapcs_next_ncrn = ncrn + nregs;
+ return;
+ }
+
+ /* C5 - Some core registers left and there are no arguments already
+ on the stack: split this argument between the remaining core
+ registers and the stack. */
+ if (ncrn < NUM_ARG_REGS && pcum->can_split)
+ {
+ pcum->aapcs_reg = gen_rtx_REG (mode, ncrn);
+ pcum->aapcs_next_ncrn = NUM_ARG_REGS;
+ pcum->aapcs_partial = (NUM_ARG_REGS - ncrn) * UNITS_PER_WORD;
+ return;
+ }
+
+ /* C6 - NCRN is set to 4. */
+ pcum->aapcs_next_ncrn = NUM_ARG_REGS;
+
+ /* C7,C8 - arugment goes on the stack. We have nothing to do here. */
+ return;
+}
+
/* Initialize a variable CUM of type CUMULATIVE_ARGS
for a call to a function whose data type is FNTYPE.
For a library call, FNTYPE is NULL. */
void
arm_init_cumulative_args (CUMULATIVE_ARGS *pcum, tree fntype,
- rtx libname ATTRIBUTE_UNUSED,
+ rtx libname,
tree fndecl ATTRIBUTE_UNUSED)
{
+ /* Long call handling. */
+ if (fntype)
+ pcum->pcs_variant = arm_get_pcs_model (fntype, fndecl);
+ else
+ pcum->pcs_variant = arm_pcs_default;
+
+ if (pcum->pcs_variant <= ARM_PCS_AAPCS_LOCAL)
+ {
+ if (arm_libcall_uses_aapcs_base (libname))
+ pcum->pcs_variant = ARM_PCS_AAPCS;
+
+ pcum->aapcs_ncrn = pcum->aapcs_next_ncrn = 0;
+ pcum->aapcs_reg = NULL_RTX;
+ pcum->aapcs_partial = 0;
+ pcum->aapcs_arg_processed = false;
+ pcum->aapcs_cprc_slot = -1;
+ pcum->can_split = true;
+
+ if (pcum->pcs_variant != ARM_PCS_AAPCS)
+ {
+ int i;
+
+ for (i = 0; i < ARM_NUM_COPROC_SLOTS; i++)
+ {
+ pcum->aapcs_cprc_failed[i] = false;
+ aapcs_cp_arg_layout[i].cum_init (pcum, fntype, libname, fndecl);
+ }
+ }
+ return;
+ }
+
+ /* Legacy ABIs */
+
/* On the ARM, the offset starts at 0. */
pcum->nregs = 0;
pcum->iwmmxt_nregs = 0;
@@ -3158,6 +4074,17 @@ arm_function_arg (CUMULATIVE_ARGS *pcum, enum machine_mode mode,
{
int nregs;
+ /* Handle the special case quickly. Pick an arbitrary value for op2 of
+ a call insn (op3 of a call_value insn). */
+ if (mode == VOIDmode)
+ return const0_rtx;
+
+ if (pcum->pcs_variant <= ARM_PCS_AAPCS_LOCAL)
+ {
+ aapcs_layout_arg (pcum, mode, type, named);
+ return pcum->aapcs_reg;
+ }
+
/* Varargs vectors are treated the same as long long.
named_count avoids having to change the way arm handles 'named' */
if (TARGET_IWMMXT_ABI
@@ -3199,10 +4126,16 @@ arm_function_arg (CUMULATIVE_ARGS *pcum, enum machine_mode mode,
static int
arm_arg_partial_bytes (CUMULATIVE_ARGS *pcum, enum machine_mode mode,
- tree type, bool named ATTRIBUTE_UNUSED)
+ tree type, bool named)
{
int nregs = pcum->nregs;
+ if (pcum->pcs_variant <= ARM_PCS_AAPCS_LOCAL)
+ {
+ aapcs_layout_arg (pcum, mode, type, named);
+ return pcum->aapcs_partial;
+ }
+
if (TARGET_IWMMXT_ABI && arm_vector_mode_supported_p (mode))
return 0;
@@ -3214,6 +4147,39 @@ arm_arg_partial_bytes (CUMULATIVE_ARGS *pcum, enum machine_mode mode,
return 0;
}
+void
+arm_function_arg_advance (CUMULATIVE_ARGS *pcum, enum machine_mode mode,
+ tree type, bool named)
+{
+ if (pcum->pcs_variant <= ARM_PCS_AAPCS_LOCAL)
+ {
+ aapcs_layout_arg (pcum, mode, type, named);
+
+ if (pcum->aapcs_cprc_slot >= 0)
+ {
+ aapcs_cp_arg_layout[pcum->aapcs_cprc_slot].advance (pcum, mode,
+ type);
+ pcum->aapcs_cprc_slot = -1;
+ }
+
+ /* Generic stuff. */
+ pcum->aapcs_arg_processed = false;
+ pcum->aapcs_ncrn = pcum->aapcs_next_ncrn;
+ pcum->aapcs_reg = NULL_RTX;
+ pcum->aapcs_partial = 0;
+ }
+ else
+ {
+ pcum->nargs += 1;
+ if (arm_vector_mode_supported_p (mode)
+ && pcum->named_count > pcum->nargs
+ && TARGET_IWMMXT_ABI)
+ pcum->iwmmxt_nregs += 1;
+ else
+ pcum->nregs += ARM_NUM_REGS2 (mode, type);
+ }
+}
+
/* Variable sized types are passed by reference. This is a GCC
extension to the ARM ABI. */
@@ -3264,6 +4230,8 @@ const struct attribute_spec arm_attribute_table[] =
/* Whereas these functions are always known to reside within the 26 bit
addressing range. */
{ "short_call", 0, 0, false, true, true, NULL },
+ /* Specify the procedure call conventions for a function. */
+ { "pcs", 1, 1, false, true, true, arm_handle_pcs_attribute },
/* Interrupt Service Routines have special prologue and epilogue requirements. */
{ "isr", 0, 1, false, false, false, arm_handle_isr_attribute },
{ "interrupt", 0, 1, false, false, false, arm_handle_isr_attribute },
@@ -3366,6 +4334,20 @@ arm_handle_isr_attribute (tree *node, tree name, tree args, int flags,
return NULL_TREE;
}
+/* Handle a "pcs" attribute; arguments as in struct
+ attribute_spec.handler. */
+static tree
+arm_handle_pcs_attribute (tree *node ATTRIBUTE_UNUSED, tree name, tree args,
+ int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
+{
+ if (arm_pcs_from_attribute (args) == ARM_PCS_UNKNOWN)
+ {
+ warning (OPT_Wattributes, "%qE attribute ignored", name);
+ *no_add_attrs = true;
+ }
+ return NULL_TREE;
+}
+
#if TARGET_DLLIMPORT_DECL_ATTRIBUTES
/* Handle the "notshared" attribute. This attribute is another way of
requesting hidden visibility. ARM's compiler supports
@@ -3527,7 +4509,7 @@ arm_is_long_call_p (tree decl)
/* Return nonzero if it is ok to make a tail-call to DECL. */
static bool
-arm_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
+arm_function_ok_for_sibcall (tree decl, tree exp)
{
unsigned long func_type;
@@ -3560,6 +4542,21 @@ arm_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
if (IS_INTERRUPT (func_type))
return false;
+ if (!VOID_TYPE_P (TREE_TYPE (DECL_RESULT (cfun->decl))))
+ {
+ /* Check that the return value locations are the same. For
+ example that we aren't returning a value from the sibling in
+ a VFP register but then need to transfer it to a core
+ register. */
+ rtx a, b;
+
+ a = arm_function_value (TREE_TYPE (exp), decl, false);
+ b = arm_function_value (TREE_TYPE (DECL_RESULT (cfun->decl)),
+ cfun->decl, false);
+ if (!rtx_equal_p (a, b))
+ return false;
+ }
+
/* Never tailcall if function may be called with a misaligned SP. */
if (IS_STACKALIGN (func_type))
return false;
@@ -9995,6 +10992,82 @@ note_invalid_constants (rtx insn, HOST_WIDE_INT address, int do_pushes)
return result;
}
+/* Convert instructions to their cc-clobbering variant if possible, since
+ that allows us to use smaller encodings. */
+
+static void
+thumb2_reorg (void)
+{
+ basic_block bb;
+ regset_head live;
+
+ INIT_REG_SET (&live);
+
+ /* We are freeing block_for_insn in the toplev to keep compatibility
+ with old MDEP_REORGS that are not CFG based. Recompute it now. */
+ compute_bb_for_insn ();
+ df_analyze ();
+
+ FOR_EACH_BB (bb)
+ {
+ rtx insn;
+
+ COPY_REG_SET (&live, DF_LR_OUT (bb));
+ df_simulate_initialize_backwards (bb, &live);
+ FOR_BB_INSNS_REVERSE (bb, insn)
+ {
+ if (NONJUMP_INSN_P (insn)
+ && !REGNO_REG_SET_P (&live, CC_REGNUM))
+ {
+ rtx pat = PATTERN (insn);
+ if (GET_CODE (pat) == SET
+ && low_register_operand (XEXP (pat, 0), SImode)
+ && thumb_16bit_operator (XEXP (pat, 1), SImode)
+ && low_register_operand (XEXP (XEXP (pat, 1), 0), SImode)
+ && low_register_operand (XEXP (XEXP (pat, 1), 1), SImode))
+ {
+ rtx dst = XEXP (pat, 0);
+ rtx src = XEXP (pat, 1);
+ rtx op0 = XEXP (src, 0);
+ rtx op1 = (GET_RTX_CLASS (GET_CODE (src)) == RTX_COMM_ARITH
+ ? XEXP (src, 1) : NULL);
+
+ if (rtx_equal_p (dst, op0)
+ || GET_CODE (src) == PLUS || GET_CODE (src) == MINUS)
+ {
+ rtx ccreg = gen_rtx_REG (CCmode, CC_REGNUM);
+ rtx clobber = gen_rtx_CLOBBER (VOIDmode, ccreg);
+ rtvec vec = gen_rtvec (2, pat, clobber);
+ PATTERN (insn) = gen_rtx_PARALLEL (VOIDmode, vec);
+ INSN_CODE (insn) = -1;
+ }
+ /* We can also handle a commutative operation where the
+ second operand matches the destination. */
+ else if (op1 && rtx_equal_p (dst, op1))
+ {
+ rtx ccreg = gen_rtx_REG (CCmode, CC_REGNUM);
+ rtx clobber = gen_rtx_CLOBBER (VOIDmode, ccreg);
+ rtvec vec;
+
+ src = copy_rtx (src);
+ XEXP (src, 0) = op1;
+ XEXP (src, 1) = op0;
+ pat = gen_rtx_SET (VOIDmode, dst, src);
+ vec = gen_rtvec (2, pat, clobber);
+ PATTERN (insn) = gen_rtx_PARALLEL (VOIDmode, vec);
+ INSN_CODE (insn) = -1;
+ }
+ }
+ }
+
+ if (NONDEBUG_INSN_P (insn))
+ df_simulate_one_insn_backwards (bb, insn, &live);
+ }
+ }
+
+ CLEAR_REG_SET (&live);
+}
+
/* Gcc puts the pool in the wrong place for ARM, since we can only
load addresses a limited distance around the pc. We do some
special munging to move the constant pool values to the correct
@@ -10006,6 +11079,9 @@ arm_reorg (void)
HOST_WIDE_INT address = 0;
Mfix * fix;
+ if (TARGET_THUMB2)
+ thumb2_reorg ();
+
minipool_fix_head = minipool_fix_tail = NULL;
/* The first insn must always be a note, or the code below won't
@@ -18823,19 +19899,24 @@ arm_output_load_gr (rtx *operands)
that way. */
static void
-arm_setup_incoming_varargs (CUMULATIVE_ARGS *cum,
+arm_setup_incoming_varargs (CUMULATIVE_ARGS *pcum,
enum machine_mode mode,
tree type,
int *pretend_size,
int second_time ATTRIBUTE_UNUSED)
{
- int nregs = cum->nregs;
- if (nregs & 1
- && ARM_DOUBLEWORD_ALIGN
- && arm_needs_doubleword_align (mode, type))
- nregs++;
+ int nregs;
cfun->machine->uses_anonymous_args = 1;
+ if (pcum->pcs_variant <= ARM_PCS_AAPCS_LOCAL)
+ {
+ nregs = pcum->aapcs_ncrn;
+ if ((nregs & 1) && arm_needs_doubleword_align (mode, type))
+ nregs++;
+ }
+ else
+ nregs = pcum->nregs;
+
if (nregs < NUM_ARG_REGS)
*pretend_size = (NUM_ARG_REGS - nregs) * UNITS_PER_WORD;
}
@@ -19219,9 +20300,10 @@ arm_vector_mode_supported_p (enum machine_mode mode)
|| mode == V16QImode || mode == V4SFmode || mode == V2DImode))
return true;
- if ((mode == V2SImode)
- || (mode == V4HImode)
- || (mode == V8QImode))
+ if ((TARGET_NEON || TARGET_IWMMXT)
+ && ((mode == V2SImode)
+ || (mode == V4HImode)
+ || (mode == V8QImode)))
return true;
return false;
@@ -19967,9 +21049,9 @@ arm_can_simplify_got_access (int n_symbol, int n_access)
}
/* Detect if INSN loads a global address. If so returns the symbol and
- stores the register contains the offset of GOT entry into OFFSET_REG. */
+ sets the corresponding OFFSET_REG and OFFSET_INSN. */
rtx
-arm_loaded_global_var (rtx insn, rtx * offset_reg)
+arm_loaded_global_var (rtx insn, rtx * offset_reg, rtx * offset_insn)
{
rtx set = single_set (insn);
rtx pic_reg = cfun->machine->pic_reg;
@@ -20014,6 +21096,7 @@ arm_loaded_global_var (rtx insn, rtx * offset_reg)
return NULL_RTX;
*offset_reg = op1;
+ *offset_insn = def_insn;
return RTVEC_ELT (XVEC (src, 0), 0);
}
@@ -20026,9 +21109,9 @@ arm_loaded_global_var (rtx insn, rtx * offset_reg)
LOAD_INSN is the original insn which loads the address from GOT. */
void
arm_load_global_address (rtx symbol, rtx offset_reg,
- rtx address_reg, rtx load_insn)
+ rtx address_reg, rtx load_insn, rtx offset_insn)
{
- rtx offset, got_prel;
+ rtx offset, got_prel, new_insn;
rtx labelno = GEN_INT (pic_labelno++);
rtx l1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, labelno), UNSPEC_PIC_LABEL);
rtx set = single_set (load_insn);
@@ -20044,22 +21127,22 @@ arm_load_global_address (rtx symbol, rtx offset_reg,
UNSPEC_GOT_PREL_SYM);
got_prel = gen_rtx_CONST (Pmode, got_prel);
if (TARGET_32BIT)
- emit_insn_before (gen_pic_load_addr_32bit (offset_reg, got_prel),
- load_insn);
+ new_insn = emit_insn_after (gen_pic_load_addr_32bit (offset_reg, got_prel),
+ offset_insn);
else
- emit_insn_before (gen_pic_load_addr_thumb1 (offset_reg, got_prel),
- load_insn);
+ new_insn = emit_insn_after (gen_pic_load_addr_thumb1 (offset_reg, got_prel),
+ offset_insn);
/* The second insn:
(SET offset_reg (PLUS offset_reg pc_rtx)) */
if (TARGET_ARM)
- emit_insn_before (gen_pic_add_dot_plus_eight (offset_reg, offset_reg,
- labelno),
- load_insn);
- else
- emit_insn_before (gen_pic_add_dot_plus_four (offset_reg, offset_reg,
+ emit_insn_after (gen_pic_add_dot_plus_eight (offset_reg, offset_reg,
labelno),
- load_insn);
+ new_insn);
+ else
+ emit_insn_after (gen_pic_add_dot_plus_four (offset_reg, offset_reg,
+ labelno),
+ new_insn);
/* The last insn to access the GOT entry:
(SET address_reg (MEM offset_reg))
diff --git a/gcc-4.4.3/gcc/config/arm/arm.h b/gcc-4.4.3/gcc/config/arm/arm.h
index a413dd323..1189914f6 100644
--- a/gcc-4.4.3/gcc/config/arm/arm.h
+++ b/gcc-4.4.3/gcc/config/arm/arm.h
@@ -880,6 +880,9 @@ extern int arm_structure_size_boundary;
/* The number of (integer) argument register available. */
#define NUM_ARG_REGS 4
+/* And similarly for the VFP. */
+#define NUM_VFP_ARG_REGS 16
+
/* Return the register number of the N'th (integer) argument. */
#define ARG_REGISTER(N) (N - 1)
@@ -1494,9 +1497,10 @@ do { \
/* Define how to find the value returned by a library function
assuming the value has mode MODE. */
-#define LIBCALL_VALUE(MODE) \
- (TARGET_32BIT && TARGET_HARD_FLOAT_ABI && TARGET_FPA \
- && GET_MODE_CLASS (MODE) == MODE_FLOAT \
+#define LIBCALL_VALUE(MODE) \
+ (TARGET_AAPCS_BASED ? aapcs_libcall_value (MODE) \
+ : (TARGET_32BIT && TARGET_HARD_FLOAT_ABI && TARGET_FPA \
+ && GET_MODE_CLASS (MODE) == MODE_FLOAT) \
? gen_rtx_REG (MODE, FIRST_FPA_REGNUM) \
: TARGET_32BIT && TARGET_HARD_FLOAT_ABI && TARGET_MAVERICK \
&& GET_MODE_CLASS (MODE) == MODE_FLOAT \
@@ -1505,22 +1509,16 @@ do { \
? gen_rtx_REG (MODE, FIRST_IWMMXT_REGNUM) \
: gen_rtx_REG (MODE, ARG_REGISTER (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 FUNCTION_VALUE(VALTYPE, FUNC) \
- arm_function_value (VALTYPE, FUNC);
-
-/* 1 if N is a possible register number for a function value.
- On the ARM, only r0 and f0 can return results. */
-/* On a Cirrus chip, mvf0 can return results. */
-#define FUNCTION_VALUE_REGNO_P(REGNO) \
- ((REGNO) == ARG_REGISTER (1) \
- || (TARGET_32BIT && ((REGNO) == FIRST_CIRRUS_FP_REGNUM) \
- && TARGET_HARD_FLOAT_ABI && TARGET_MAVERICK) \
- || ((REGNO) == FIRST_IWMMXT_REGNUM && TARGET_IWMMXT_ABI) \
- || (TARGET_32BIT && ((REGNO) == FIRST_FPA_REGNUM) \
+/* 1 if REGNO is a possible register number for a function value. */
+#define FUNCTION_VALUE_REGNO_P(REGNO) \
+ ((REGNO) == ARG_REGISTER (1) \
+ || (TARGET_AAPCS_BASED && TARGET_32BIT \
+ && TARGET_VFP && TARGET_HARD_FLOAT \
+ && (REGNO) == FIRST_VFP_REGNUM) \
+ || (TARGET_32BIT && ((REGNO) == FIRST_CIRRUS_FP_REGNUM) \
+ && TARGET_HARD_FLOAT_ABI && TARGET_MAVERICK) \
+ || ((REGNO) == FIRST_IWMMXT_REGNUM && TARGET_IWMMXT_ABI) \
+ || (TARGET_32BIT && ((REGNO) == FIRST_FPA_REGNUM) \
&& TARGET_HARD_FLOAT_ABI && TARGET_FPA))
/* Amount of memory needed for an untyped call to save all possible return
@@ -1620,9 +1618,27 @@ machine_function;
that is in text_section. */
extern GTY(()) rtx thumb_call_via_label[14];
+/* The number of potential ways of assigning to a co-processor. */
+#define ARM_NUM_COPROC_SLOTS 1
+
+/* Enumeration of procedure calling standard variants. We don't really
+ support all of these yet. */
+enum arm_pcs
+{
+ ARM_PCS_AAPCS, /* Base standard AAPCS. */
+ ARM_PCS_AAPCS_VFP, /* Use VFP registers for floating point values. */
+ ARM_PCS_AAPCS_IWMMXT, /* Use iWMMXT registers for vectors. */
+ /* This must be the last AAPCS variant. */
+ ARM_PCS_AAPCS_LOCAL, /* Private call within this compilation unit. */
+ ARM_PCS_ATPCS, /* ATPCS. */
+ ARM_PCS_APCS, /* APCS (legacy Linux etc). */
+ ARM_PCS_UNKNOWN
+};
+
+/* We can't define this inside a generator file because it needs enum
+ machine_mode. */
/* A C type for declaring a variable that is used as the first argument of
- `FUNCTION_ARG' and other related values. For some target machines, the
- type `int' suffices and can hold the number of bytes of argument so far. */
+ `FUNCTION_ARG' and other related values. */
typedef struct
{
/* This is the number of registers of arguments scanned so far. */
@@ -1631,7 +1647,30 @@ typedef struct
int iwmmxt_nregs;
int named_count;
int nargs;
- int can_split;
+ /* Which procedure call variant to use for this call. */
+ enum arm_pcs pcs_variant;
+
+ /* AAPCS related state tracking. */
+ int aapcs_arg_processed; /* No need to lay out this argument again. */
+ int aapcs_cprc_slot; /* Index of co-processor rules to handle
+ this argument, or -1 if using core
+ registers. */
+ int aapcs_ncrn;
+ int aapcs_next_ncrn;
+ rtx aapcs_reg; /* Register assigned to this argument. */
+ int aapcs_partial; /* How many bytes are passed in regs (if
+ split between core regs and stack.
+ Zero otherwise. */
+ int aapcs_cprc_failed[ARM_NUM_COPROC_SLOTS];
+ int can_split; /* Argument can be split between core regs
+ and the stack. */
+ /* Private data for tracking VFP register allocation */
+ unsigned aapcs_vfp_regs_free;
+ unsigned aapcs_vfp_reg_alloc;
+ int aapcs_vfp_rcount;
+ /* Can't include insn-modes.h because this header is needed before we
+ generate it. */
+ int /* enum machine_mode */ aapcs_vfp_rmode;
} CUMULATIVE_ARGS;
/* Define where to put the arguments to a function.
@@ -1677,13 +1716,7 @@ typedef struct
of mode MODE and data type TYPE.
(TYPE is null for libcalls where that information may not be available.) */
#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
- (CUM).nargs += 1; \
- if (arm_vector_mode_supported_p (MODE) \
- && (CUM).named_count > (CUM).nargs \
- && TARGET_IWMMXT_ABI) \
- (CUM).iwmmxt_nregs += 1; \
- else \
- (CUM).nregs += ARM_NUM_REGS2 (MODE, TYPE)
+ arm_function_arg_advance (&(CUM), (MODE), (TYPE), (NAMED))
/* If defined, a C expression that gives the alignment boundary, in bits, of an
argument with the specified mode and type. If it is not defined,
@@ -1695,9 +1728,11 @@ typedef struct
/* 1 if N is a possible register number for function argument passing.
On the ARM, r0-r3 are used to pass args. */
-#define FUNCTION_ARG_REGNO_P(REGNO) \
- (IN_RANGE ((REGNO), 0, 3) \
- || (TARGET_IWMMXT_ABI \
+#define FUNCTION_ARG_REGNO_P(REGNO) \
+ (IN_RANGE ((REGNO), 0, 3) \
+ || (TARGET_AAPCS_BASED && TARGET_VFP && TARGET_HARD_FLOAT \
+ && IN_RANGE ((REGNO), FIRST_VFP_REGNUM, FIRST_VFP_REGNUM + 15)) \
+ || (TARGET_IWMMXT_ABI \
&& IN_RANGE ((REGNO), FIRST_IWMMXT_REGNUM, FIRST_IWMMXT_REGNUM + 9)))
diff --git a/gcc-4.4.3/gcc/config/arm/arm.md b/gcc-4.4.3/gcc/config/arm/arm.md
index e9de45efd..ea16f1c31 100644
--- a/gcc-4.4.3/gcc/config/arm/arm.md
+++ b/gcc-4.4.3/gcc/config/arm/arm.md
@@ -743,14 +743,14 @@
[(set (reg:CC CC_REGNUM)
(compare:CC
(match_operand:SI 1 "s_register_operand" "r,r")
- (match_operand:SI 2 "arm_addimm_operand" "I,L")))
+ (match_operand:SI 2 "arm_addimm_operand" "L,I")))
(set (match_operand:SI 0 "s_register_operand" "=r,r")
(plus:SI (match_dup 1)
- (match_operand:SI 3 "arm_addimm_operand" "L,I")))]
+ (match_operand:SI 3 "arm_addimm_operand" "I,L")))]
"TARGET_32BIT && INTVAL (operands[2]) == -INTVAL (operands[3])"
"@
- sub%.\\t%0, %1, %2
- add%.\\t%0, %1, #%n2"
+ add%.\\t%0, %1, %3
+ sub%.\\t%0, %1, #%n3"
[(set_attr "conds" "set")]
)
@@ -1907,9 +1907,17 @@
{
if (GET_CODE (operands[2]) == CONST_INT)
{
- arm_split_constant (AND, SImode, NULL_RTX,
- INTVAL (operands[2]), operands[0],
- operands[1], optimize && can_create_pseudo_p ());
+ if (INTVAL (operands[2]) == 255 && arm_arch6)
+ {
+ operands[1] = convert_to_mode (QImode, operands[1], 1);
+ emit_insn (gen_thumb2_zero_extendqisi2_v6 (operands[0],
+ operands[1]));
+ }
+ else
+ arm_split_constant (AND, SImode, NULL_RTX,
+ INTVAL (operands[2]), operands[0],
+ operands[1],
+ optimize && can_create_pseudo_p ());
DONE;
}
diff --git a/gcc-4.4.3/gcc/config/arm/bpabi.h b/gcc-4.4.3/gcc/config/arm/bpabi.h
index 4d2974e32..4b37dcf63 100644
--- a/gcc-4.4.3/gcc/config/arm/bpabi.h
+++ b/gcc-4.4.3/gcc/config/arm/bpabi.h
@@ -90,16 +90,22 @@
#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (muldi3, lmul)
#endif
#ifdef L_fixdfdi
-#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (fixdfdi, d2lz)
+#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (fixdfdi, d2lz) \
+ extern DWtype __fixdfdi (DFtype) __attribute__((pcs("aapcs"))); \
+ extern UDWtype __fixunsdfdi (DFtype) __asm__("__aeabi_d2ulz") __attribute__((pcs("aapcs")));
#endif
#ifdef L_fixunsdfdi
-#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (fixunsdfdi, d2ulz)
+#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (fixunsdfdi, d2ulz) \
+ extern UDWtype __fixunsdfdi (DFtype) __attribute__((pcs("aapcs")));
#endif
#ifdef L_fixsfdi
-#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (fixsfdi, f2lz)
+#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (fixsfdi, f2lz) \
+ extern DWtype __fixsfdi (SFtype) __attribute__((pcs("aapcs"))); \
+ extern UDWtype __fixunssfdi (SFtype) __asm__("__aeabi_f2ulz") __attribute__((pcs("aapcs")));
#endif
#ifdef L_fixunssfdi
-#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (fixunssfdi, f2ulz)
+#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (fixunssfdi, f2ulz) \
+ extern UDWtype __fixunssfdi (SFtype) __attribute__((pcs("aapcs")));
#endif
#ifdef L_floatdidf
#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (floatdidf, l2d)
diff --git a/gcc-4.4.3/gcc/config/arm/constraints.md b/gcc-4.4.3/gcc/config/arm/constraints.md
index d14dafd2b..8cab39a66 100644
--- a/gcc-4.4.3/gcc/config/arm/constraints.md
+++ b/gcc-4.4.3/gcc/config/arm/constraints.md
@@ -31,6 +31,7 @@
;; The following multi-letter normal constraints have been used:
;; in ARM/Thumb-2 state: Da, Db, Dc, Dn, Dl, DL, Dv
;; in Thumb-1 state: Pa, Pb
+;; in Thumb-2 state: Ps, Pt, Pw, Px
;; The following memory constraints have been used:
;; in ARM/Thumb-2 state: Q, Ut, Uv, Uy, Un, Us
@@ -149,6 +150,26 @@
(match_test "TARGET_THUMB1 && ival >= -262 && ival <= 262
&& (ival > 255 || ival < -255)")))
+(define_constraint "Ps"
+ "@internal In Thumb-2 state a constant in the range -255 to +255"
+ (and (match_code "const_int")
+ (match_test "TARGET_THUMB2 && ival >= -255 && ival <= 255")))
+
+(define_constraint "Pt"
+ "@internal In Thumb-2 state a constant in the range -7 to +7"
+ (and (match_code "const_int")
+ (match_test "TARGET_THUMB2 && ival >= -7 && ival <= 7")))
+
+(define_constraint "Pw"
+ "@internal In Thumb-2 state a constant in the range -255 to -1"
+ (and (match_code "const_int")
+ (match_test "TARGET_THUMB2 && ival >= -255 && ival <= -1")))
+
+(define_constraint "Px"
+ "@internal In Thumb-2 state a constant in the range -7 to -1"
+ (and (match_code "const_int")
+ (match_test "TARGET_THUMB2 && ival >= -7 && ival <= -1")))
+
(define_constraint "G"
"In ARM/Thumb-2 state a valid FPA immediate constant."
(and (match_code "const_double")
diff --git a/gcc-4.4.3/gcc/config/arm/linux-eabi.h b/gcc-4.4.3/gcc/config/arm/linux-eabi.h
index 6dd44436a..2ca881890 100644
--- a/gcc-4.4.3/gcc/config/arm/linux-eabi.h
+++ b/gcc-4.4.3/gcc/config/arm/linux-eabi.h
@@ -27,6 +27,7 @@
{ \
TARGET_BPABI_CPP_BUILTINS(); \
LINUX_TARGET_OS_CPP_BUILTINS(); \
+ ANDROID_TARGET_OS_CPP_BUILTINS(); \
} \
while (false)
diff --git a/gcc-4.4.3/gcc/config/arm/t-arm-elf b/gcc-4.4.3/gcc/config/arm/t-arm-elf
index 9f6068258..5b812b750 100644
--- a/gcc-4.4.3/gcc/config/arm/t-arm-elf
+++ b/gcc-4.4.3/gcc/config/arm/t-arm-elf
@@ -32,6 +32,13 @@ MULTILIB_OPTIONS += $(MLOPT_armv7a)
MULTILIB_DIRNAMES += $(MLDIR_armv7a)
MULTILIB_MATCHES += $(MLMATCH_armv7a)
+# Not quite true. We can support hard-vfp calling in Thumb2, but how do we
+# express that here? Also, we really need architecture v5e or later
+# (mcrr etc).
+MULTILIB_OPTIONS += mfloat-abi=hard
+MULTILIB_DIRNAMES += fpu
+MULTILIB_EXCEPTIONS += *mthumb/*mfloat-abi=hard*
+
# MULTILIB_OPTIONS += mcpu=ep9312
# MULTILIB_DIRNAMES += ep9312
# MULTILIB_EXCEPTIONS += *mthumb/*mcpu=ep9312*
diff --git a/gcc-4.4.3/gcc/config/arm/thumb2.md b/gcc-4.4.3/gcc/config/arm/thumb2.md
index 2243172e6..6e03e8b21 100644
--- a/gcc-4.4.3/gcc/config/arm/thumb2.md
+++ b/gcc-4.4.3/gcc/config/arm/thumb2.md
@@ -943,7 +943,7 @@
(set_attr "neg_pool_range" "*,250")]
)
-(define_insn "*thumb2_zero_extendqisi2_v6"
+(define_insn "thumb2_zero_extendqisi2_v6"
[(set (match_operand:SI 0 "s_register_operand" "=r,r")
(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
"TARGET_THUMB2 && arm_arch6"
@@ -1006,29 +1006,6 @@
}"
)
-;; Peepholes and insns for 16-bit flag clobbering instructions.
-;; The conditional forms of these instructions do not clobber CC.
-;; However by the time peepholes are run it is probably too late to do
-;; anything useful with this information.
-(define_peephole2
- [(set (match_operand:SI 0 "low_register_operand" "")
- (match_operator:SI 3 "thumb_16bit_operator"
- [(match_operand:SI 1 "low_register_operand" "")
- (match_operand:SI 2 "low_register_operand" "")]))]
- "TARGET_THUMB2
- && (rtx_equal_p(operands[0], operands[1])
- || GET_CODE(operands[3]) == PLUS
- || GET_CODE(operands[3]) == MINUS)
- && peep2_regno_dead_p(0, CC_REGNUM)"
- [(parallel
- [(set (match_dup 0)
- (match_op_dup 3
- [(match_dup 1)
- (match_dup 2)]))
- (clobber (reg:CC CC_REGNUM))])]
- ""
-)
-
(define_insn "*thumb2_alusi3_short"
[(set (match_operand:SI 0 "s_register_operand" "=l")
(match_operator:SI 3 "thumb_16bit_operator"
@@ -1124,9 +1101,9 @@
)
(define_insn "*thumb2_addsi_short"
- [(set (match_operand:SI 0 "low_register_operand" "=l")
- (plus:SI (match_operand:SI 1 "low_register_operand" "l")
- (match_operand:SI 2 "low_reg_or_int_operand" "lIL")))
+ [(set (match_operand:SI 0 "low_register_operand" "=l,l")
+ (plus:SI (match_operand:SI 1 "low_register_operand" "l,0")
+ (match_operand:SI 2 "low_reg_or_int_operand" "lPt,Ps")))
(clobber (reg:CC CC_REGNUM))]
"TARGET_THUMB2 && reload_completed"
"*
@@ -1178,6 +1155,32 @@
(set_attr "length" "2")]
)
+(define_peephole2
+ [(set (match_operand:CC 0 "cc_register" "")
+ (compare:CC (match_operand:SI 1 "low_register_operand" "")
+ (match_operand:SI 2 "const_int_operand" "")))]
+ "TARGET_THUMB2
+ && peep2_reg_dead_p (1, operands[1])
+ && satisfies_constraint_Pw (operands[2])"
+ [(parallel
+ [(set (match_dup 0) (compare:CC (match_dup 1) (match_dup 2)))
+ (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 3)))])]
+ "operands[3] = GEN_INT (- INTVAL (operands[2]));"
+)
+
+(define_peephole2
+ [(match_scratch:SI 3 "l")
+ (set (match_operand:CC 0 "cc_register" "")
+ (compare:CC (match_operand:SI 1 "low_register_operand" "")
+ (match_operand:SI 2 "const_int_operand" "")))]
+ "TARGET_THUMB2
+ && satisfies_constraint_Px (operands[2])"
+ [(parallel
+ [(set (match_dup 0) (compare:CC (match_dup 1) (match_dup 2)))
+ (set (match_dup 3) (plus:SI (match_dup 1) (match_dup 4)))])]
+ "operands[4] = GEN_INT (- INTVAL (operands[2]));"
+)
+
(define_insn "*thumb2_cbz"
[(set (pc) (if_then_else
(eq (match_operand:SI 0 "s_register_operand" "l,?r")
diff --git a/gcc-4.4.3/gcc/config/i386/atom.md b/gcc-4.4.3/gcc/config/i386/atom.md
new file mode 100644
index 000000000..1664269ba
--- /dev/null
+++ b/gcc-4.4.3/gcc/config/i386/atom.md
@@ -0,0 +1,796 @@
+;; Atom Scheduling
+;; Copyright (C) 2009 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/>.
+;;
+;; Atom is an in-order core with two integer pipelines.
+
+
+(define_attr "atom_unit" "sishuf,simul,jeu,complex,other"
+ (const_string "other"))
+
+(define_attr "atom_sse_attr" "rcp,movdup,lfence,fence,prefetch,sqrt,mxcsr,other"
+ (const_string "other"))
+
+(define_automaton "atom")
+
+;; Atom has two ports: port 0 and port 1 connecting to all execution units
+(define_cpu_unit "atom-port-0,atom-port-1" "atom")
+
+;; EU: Execution Unit
+;; Atom EUs are connected by port 0 or port 1.
+
+(define_cpu_unit "atom-eu-0, atom-eu-1,
+ atom-imul-1, atom-imul-2, atom-imul-3, atom-imul-4"
+ "atom")
+
+;; Some EUs have duplicated copied and can be accessed via either
+;; port 0 or port 1
+;; (define_reservation "atom-port-either" "(atom-port-0 | atom-port-1)")
+
+;;; Some instructions is dual-pipe execution, need both ports
+;;; Complex multi-op macro-instructoins need both ports and all EUs
+(define_reservation "atom-port-dual" "(atom-port-0 + atom-port-1)")
+(define_reservation "atom-all-eu" "(atom-eu-0 + atom-eu-1 +
+ atom-imul-1 + atom-imul-2 + atom-imul-3 +
+ atom-imul-4)")
+
+;;; Most of simple instructions have 1 cycle latency. Some of them
+;;; issue in port 0, some in port 0 and some in either port.
+(define_reservation "atom-simple-0" "(atom-port-0 + atom-eu-0)")
+(define_reservation "atom-simple-1" "(atom-port-1 + atom-eu-1)")
+(define_reservation "atom-simple-either" "(atom-simple-0 | atom-simple-1)")
+
+;;; Some insn issues in port 0 with 3 cycle latency and 1 cycle tput
+(define_reservation "atom-eu-0-3-1" "(atom-port-0 + atom-eu-0, nothing*2)")
+
+;;; fmul insn can have 4 or 5 cycles latency
+(define_reservation "atom-fmul-5c" "(atom-port-0 + atom-eu-0), nothing*4")
+(define_reservation "atom-fmul-4c" "(atom-port-0 + atom-eu-0), nothing*3")
+
+;;; fadd can has 5 cycles latency depends on instruction forms
+(define_reservation "atom-fadd-5c" "(atom-port-1 + atom-eu-1), nothing*5")
+
+;;; imul insn has 5 cycles latency
+(define_reservation "atom-imul-32"
+ "atom-imul-1, atom-imul-2, atom-imul-3, atom-imul-4,
+ atom-port-0")
+;;; imul instruction excludes other non-FP instructions.
+(exclusion_set "atom-eu-0, atom-eu-1"
+ "atom-imul-1, atom-imul-2, atom-imul-3, atom-imul-4")
+
+;;; dual-execution instructions can have 1,2,4,5 cycles latency depends on
+;;; instruction forms
+(define_reservation "atom-dual-1c" "(atom-port-dual + atom-eu-0 + atom-eu-1)")
+(define_reservation "atom-dual-2c"
+ "(atom-port-dual + atom-eu-0 + atom-eu-1, nothing)")
+(define_reservation "atom-dual-5c"
+ "(atom-port-dual + atom-eu-0 + atom-eu-1, nothing*4)")
+
+;;; Complex macro-instruction has variants of latency, and uses both ports.
+(define_reservation "atom-complex" "(atom-port-dual + atom-all-eu)")
+
+(define_insn_reservation "atom_other" 9
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "other")
+ (eq_attr "atom_unit" "!jeu")))
+ "atom-complex, atom-all-eu*8")
+
+;; return has type "other" with atom_unit "jeu"
+(define_insn_reservation "atom_other_2" 1
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "other")
+ (eq_attr "atom_unit" "jeu")))
+ "atom-dual-1c")
+
+(define_insn_reservation "atom_multi" 9
+ (and (eq_attr "cpu" "atom")
+ (eq_attr "type" "multi"))
+ "atom-complex, atom-all-eu*8")
+
+;; Normal alu insns without carry
+(define_insn_reservation "atom_alu" 1
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "alu")
+ (and (eq_attr "memory" "none")
+ (eq_attr "use_carry" "0"))))
+ "atom-simple-either")
+
+;; Normal alu insns without carry
+(define_insn_reservation "atom_alu_mem" 1
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "alu")
+ (and (eq_attr "memory" "!none")
+ (eq_attr "use_carry" "0"))))
+ "atom-simple-either")
+
+;; Alu insn consuming CF, such as add/sbb
+(define_insn_reservation "atom_alu_carry" 1
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "alu")
+ (and (eq_attr "memory" "none")
+ (eq_attr "use_carry" "1"))))
+ "atom-simple-either")
+
+;; Alu insn consuming CF, such as add/sbb
+(define_insn_reservation "atom_alu_carry_mem" 1
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "alu")
+ (and (eq_attr "memory" "!none")
+ (eq_attr "use_carry" "1"))))
+ "atom-simple-either")
+
+(define_insn_reservation "atom_alu1" 1
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "alu1")
+ (eq_attr "memory" "none")))
+ "atom-simple-either")
+
+(define_insn_reservation "atom_alu1_mem" 1
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "alu1")
+ (eq_attr "memory" "!none")))
+ "atom-simple-either")
+
+(define_insn_reservation "atom_negnot" 1
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "negnot")
+ (eq_attr "memory" "none")))
+ "atom-simple-either")
+
+(define_insn_reservation "atom_negnot_mem" 1
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "negnot")
+ (eq_attr "memory" "!none")))
+ "atom-simple-either")
+
+(define_insn_reservation "atom_imov" 1
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "imov")
+ (eq_attr "memory" "none")))
+ "atom-simple-either")
+
+(define_insn_reservation "atom_imov_mem" 1
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "imov")
+ (eq_attr "memory" "!none")))
+ "atom-simple-either")
+
+;; 16<-16, 32<-32
+(define_insn_reservation "atom_imovx" 1
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "imovx")
+ (and (eq_attr "memory" "none")
+ (ior (and (match_operand:HI 0 "register_operand")
+ (match_operand:HI 1 "general_operand"))
+ (and (match_operand:SI 0 "register_operand")
+ (match_operand:SI 1 "general_operand"))))))
+ "atom-simple-either")
+
+;; 16<-16, 32<-32, mem
+(define_insn_reservation "atom_imovx_mem" 1
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "imovx")
+ (and (eq_attr "memory" "!none")
+ (ior (and (match_operand:HI 0 "register_operand")
+ (match_operand:HI 1 "general_operand"))
+ (and (match_operand:SI 0 "register_operand")
+ (match_operand:SI 1 "general_operand"))))))
+ "atom-simple-either")
+
+;; 32<-16, 32<-8, 64<-16, 64<-8, 64<-32, 8<-8
+(define_insn_reservation "atom_imovx_2" 1
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "imovx")
+ (and (eq_attr "memory" "none")
+ (ior (match_operand:QI 0 "register_operand")
+ (ior (and (match_operand:SI 0 "register_operand")
+ (not (match_operand:SI 1 "general_operand")))
+ (match_operand:DI 0 "register_operand"))))))
+ "atom-simple-0")
+
+;; 32<-16, 32<-8, 64<-16, 64<-8, 64<-32, 8<-8, mem
+(define_insn_reservation "atom_imovx_2_mem" 1
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "imovx")
+ (and (eq_attr "memory" "!none")
+ (ior (match_operand:QI 0 "register_operand")
+ (ior (and (match_operand:SI 0 "register_operand")
+ (not (match_operand:SI 1 "general_operand")))
+ (match_operand:DI 0 "register_operand"))))))
+ "atom-simple-0")
+
+;; 16<-8
+(define_insn_reservation "atom_imovx_3" 3
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "imovx")
+ (and (match_operand:HI 0 "register_operand")
+ (match_operand:QI 1 "general_operand"))))
+ "atom-complex, atom-all-eu*2")
+
+(define_insn_reservation "atom_lea" 1
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "lea")
+ (eq_attr "mode" "!HI")))
+ "atom-simple-either")
+
+;; lea 16bit address is complex insn
+(define_insn_reservation "atom_lea_2" 2
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "lea")
+ (eq_attr "mode" "HI")))
+ "atom-complex, atom-all-eu")
+
+(define_insn_reservation "atom_incdec" 1
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "incdec")
+ (eq_attr "memory" "none")))
+ "atom-simple-either")
+
+(define_insn_reservation "atom_incdec_mem" 1
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "incdec")
+ (eq_attr "memory" "!none")))
+ "atom-simple-either")
+
+;; simple shift instruction use SHIFT eu, none memory
+(define_insn_reservation "atom_ishift" 1
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "ishift")
+ (and (eq_attr "memory" "none") (eq_attr "prefix_0f" "0"))))
+ "atom-simple-0")
+
+;; simple shift instruction use SHIFT eu, memory
+(define_insn_reservation "atom_ishift_mem" 1
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "ishift")
+ (and (eq_attr "memory" "!none") (eq_attr "prefix_0f" "0"))))
+ "atom-simple-0")
+
+;; DF shift (prefixed with 0f) is complex insn with latency of 7 cycles
+(define_insn_reservation "atom_ishift_3" 7
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "ishift")
+ (eq_attr "prefix_0f" "1")))
+ "atom-complex, atom-all-eu*6")
+
+(define_insn_reservation "atom_ishift1" 1
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "ishift1")
+ (eq_attr "memory" "none")))
+ "atom-simple-0")
+
+(define_insn_reservation "atom_ishift1_mem" 1
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "ishift1")
+ (eq_attr "memory" "!none")))
+ "atom-simple-0")
+
+(define_insn_reservation "atom_rotate" 1
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "rotate")
+ (eq_attr "memory" "none")))
+ "atom-simple-0")
+
+(define_insn_reservation "atom_rotate_mem" 1
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "rotate")
+ (eq_attr "memory" "!none")))
+ "atom-simple-0")
+
+(define_insn_reservation "atom_rotate1" 1
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "rotate1")
+ (eq_attr "memory" "none")))
+ "atom-simple-0")
+
+(define_insn_reservation "atom_rotate1_mem" 1
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "rotate1")
+ (eq_attr "memory" "!none")))
+ "atom-simple-0")
+
+(define_insn_reservation "atom_imul" 5
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "imul")
+ (and (eq_attr "memory" "none") (eq_attr "mode" "SI"))))
+ "atom-imul-32")
+
+(define_insn_reservation "atom_imul_mem" 5
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "imul")
+ (and (eq_attr "memory" "!none") (eq_attr "mode" "SI"))))
+ "atom-imul-32")
+
+;; latency set to 10 as common 64x64 imul
+(define_insn_reservation "atom_imul_3" 10
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "imul")
+ (eq_attr "mode" "!SI")))
+ "atom-complex, atom-all-eu*9")
+
+(define_insn_reservation "atom_idiv" 65
+ (and (eq_attr "cpu" "atom")
+ (eq_attr "type" "idiv"))
+ "atom-complex, atom-all-eu*32, nothing*32")
+
+(define_insn_reservation "atom_icmp" 1
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "icmp")
+ (eq_attr "memory" "none")))
+ "atom-simple-either")
+
+(define_insn_reservation "atom_icmp_mem" 1
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "icmp")
+ (eq_attr "memory" "!none")))
+ "atom-simple-either")
+
+(define_insn_reservation "atom_test" 1
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "test")
+ (eq_attr "memory" "none")))
+ "atom-simple-either")
+
+(define_insn_reservation "atom_test_mem" 1
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "test")
+ (eq_attr "memory" "!none")))
+ "atom-simple-either")
+
+(define_insn_reservation "atom_ibr" 1
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "ibr")
+ (eq_attr "memory" "!load")))
+ "atom-simple-1")
+
+;; complex if jump target is from address
+(define_insn_reservation "atom_ibr_2" 2
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "ibr")
+ (eq_attr "memory" "load")))
+ "atom-complex, atom-all-eu")
+
+(define_insn_reservation "atom_setcc" 1
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "setcc")
+ (eq_attr "memory" "!store")))
+ "atom-simple-either")
+
+;; 2 cycles complex if target is in memory
+(define_insn_reservation "atom_setcc_2" 2
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "setcc")
+ (eq_attr "memory" "store")))
+ "atom-complex, atom-all-eu")
+
+(define_insn_reservation "atom_icmov" 1
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "icmov")
+ (eq_attr "memory" "none")))
+ "atom-simple-either")
+
+(define_insn_reservation "atom_icmov_mem" 1
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "icmov")
+ (eq_attr "memory" "!none")))
+ "atom-simple-either")
+
+;; UCODE if segreg, ignored
+(define_insn_reservation "atom_push" 2
+ (and (eq_attr "cpu" "atom")
+ (eq_attr "type" "push"))
+ "atom-dual-2c")
+
+;; pop r64 is 1 cycle. UCODE if segreg, ignored
+(define_insn_reservation "atom_pop" 1
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "pop")
+ (eq_attr "mode" "DI")))
+ "atom-dual-1c")
+
+;; pop non-r64 is 2 cycles. UCODE if segreg, ignored
+(define_insn_reservation "atom_pop_2" 2
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "pop")
+ (eq_attr "mode" "!DI")))
+ "atom-dual-2c")
+
+;; UCODE if segreg, ignored
+(define_insn_reservation "atom_call" 1
+ (and (eq_attr "cpu" "atom")
+ (eq_attr "type" "call"))
+ "atom-dual-1c")
+
+(define_insn_reservation "atom_callv" 1
+ (and (eq_attr "cpu" "atom")
+ (eq_attr "type" "callv"))
+ "atom-dual-1c")
+
+(define_insn_reservation "atom_leave" 3
+ (and (eq_attr "cpu" "atom")
+ (eq_attr "type" "leave"))
+ "atom-complex, atom-all-eu*2")
+
+(define_insn_reservation "atom_str" 3
+ (and (eq_attr "cpu" "atom")
+ (eq_attr "type" "str"))
+ "atom-complex, atom-all-eu*2")
+
+(define_insn_reservation "atom_sselog" 1
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "sselog")
+ (eq_attr "memory" "none")))
+ "atom-simple-either")
+
+(define_insn_reservation "atom_sselog_mem" 1
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "sselog")
+ (eq_attr "memory" "!none")))
+ "atom-simple-either")
+
+(define_insn_reservation "atom_sselog1" 1
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "sselog1")
+ (eq_attr "memory" "none")))
+ "atom-simple-0")
+
+(define_insn_reservation "atom_sselog1_mem" 1
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "sselog1")
+ (eq_attr "memory" "!none")))
+ "atom-simple-0")
+
+;; not pmad, not psad
+(define_insn_reservation "atom_sseiadd" 1
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "sseiadd")
+ (and (not (match_operand:V2DI 0 "register_operand"))
+ (and (eq_attr "atom_unit" "!simul")
+ (eq_attr "atom_unit" "!complex")))))
+ "atom-simple-either")
+
+;; pmad, psad and 64
+(define_insn_reservation "atom_sseiadd_2" 4
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "sseiadd")
+ (and (not (match_operand:V2DI 0 "register_operand"))
+ (and (eq_attr "atom_unit" "simul" )
+ (eq_attr "mode" "DI")))))
+ "atom-fmul-4c")
+
+;; pmad, psad and 128
+(define_insn_reservation "atom_sseiadd_3" 5
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "sseiadd")
+ (and (not (match_operand:V2DI 0 "register_operand"))
+ (and (eq_attr "atom_unit" "simul" )
+ (eq_attr "mode" "TI")))))
+ "atom-fmul-5c")
+
+;; if paddq(64 bit op), phadd/phsub
+(define_insn_reservation "atom_sseiadd_4" 6
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "sseiadd")
+ (ior (match_operand:V2DI 0 "register_operand")
+ (eq_attr "atom_unit" "complex"))))
+ "atom-complex, atom-all-eu*5")
+
+;; if immediate op.
+(define_insn_reservation "atom_sseishft" 1
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "sseishft")
+ (and (eq_attr "atom_unit" "!sishuf")
+ (match_operand 2 "immediate_operand"))))
+ "atom-simple-either")
+
+;; if palignr or psrldq
+(define_insn_reservation "atom_sseishft_2" 1
+ (and (eq_attr "cpu" "atom")
+ (ior (eq_attr "type" "sseishft1")
+ (and (eq_attr "type" "sseishft")
+ (and (eq_attr "atom_unit" "sishuf")
+ (match_operand 2 "immediate_operand")))))
+ "atom-simple-0")
+
+;; if reg/mem op
+(define_insn_reservation "atom_sseishft_3" 2
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "sseishft")
+ (not (match_operand 2 "immediate_operand"))))
+ "atom-complex, atom-all-eu")
+
+(define_insn_reservation "atom_sseimul" 1
+ (and (eq_attr "cpu" "atom")
+ (eq_attr "type" "sseimul"))
+ "atom-simple-0")
+
+;; rcpss or rsqrtss
+(define_insn_reservation "atom_sse" 4
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "sse")
+ (and (eq_attr "atom_sse_attr" "rcp") (eq_attr "mode" "SF"))))
+ "atom-fmul-4c")
+
+;; movshdup, movsldup. Suggest to type sseishft
+(define_insn_reservation "atom_sse_2" 1
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "sse")
+ (eq_attr "atom_sse_attr" "movdup")))
+ "atom-simple-0")
+
+;; lfence
+(define_insn_reservation "atom_sse_3" 1
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "sse")
+ (eq_attr "atom_sse_attr" "lfence")))
+ "atom-simple-either")
+
+;; sfence,clflush,mfence, prefetch
+(define_insn_reservation "atom_sse_4" 1
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "sse")
+ (ior (eq_attr "atom_sse_attr" "fence")
+ (eq_attr "atom_sse_attr" "prefetch"))))
+ "atom-simple-0")
+
+;; rcpps, rsqrtss, sqrt, ldmxcsr
+(define_insn_reservation "atom_sse_5" 7
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "sse")
+ (ior (ior (eq_attr "atom_sse_attr" "sqrt")
+ (eq_attr "atom_sse_attr" "mxcsr"))
+ (and (eq_attr "atom_sse_attr" "rcp")
+ (eq_attr "mode" "V4SF")))))
+ "atom-complex, atom-all-eu*6")
+
+;; xmm->xmm
+(define_insn_reservation "atom_ssemov" 1
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "ssemov")
+ (and (match_operand 0 "register_operand" "xy") (match_operand 1 "register_operand" "xy"))))
+ "atom-simple-either")
+
+;; reg->xmm
+(define_insn_reservation "atom_ssemov_2" 1
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "ssemov")
+ (and (match_operand 0 "register_operand" "xy") (match_operand 1 "register_operand" "r"))))
+ "atom-simple-0")
+
+;; xmm->reg
+(define_insn_reservation "atom_ssemov_3" 3
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "ssemov")
+ (and (match_operand 0 "register_operand" "r") (match_operand 1 "register_operand" "xy"))))
+ "atom-eu-0-3-1")
+
+;; mov mem
+(define_insn_reservation "atom_ssemov_4" 1
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "ssemov")
+ (and (eq_attr "movu" "0") (eq_attr "memory" "!none"))))
+ "atom-simple-0")
+
+;; movu mem
+(define_insn_reservation "atom_ssemov_5" 2
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "ssemov")
+ (ior (eq_attr "movu" "1") (eq_attr "memory" "!none"))))
+ "atom-complex, atom-all-eu")
+
+;; no memory simple
+(define_insn_reservation "atom_sseadd" 5
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "sseadd")
+ (and (eq_attr "memory" "none")
+ (and (eq_attr "mode" "!V2DF")
+ (eq_attr "atom_unit" "!complex")))))
+ "atom-fadd-5c")
+
+;; memory simple
+(define_insn_reservation "atom_sseadd_mem" 5
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "sseadd")
+ (and (eq_attr "memory" "!none")
+ (and (eq_attr "mode" "!V2DF")
+ (eq_attr "atom_unit" "!complex")))))
+ "atom-dual-5c")
+
+;; maxps, minps, *pd, hadd, hsub
+(define_insn_reservation "atom_sseadd_3" 8
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "sseadd")
+ (ior (eq_attr "mode" "V2DF") (eq_attr "atom_unit" "complex"))))
+ "atom-complex, atom-all-eu*7")
+
+;; Except dppd/dpps
+(define_insn_reservation "atom_ssemul" 5
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "ssemul")
+ (eq_attr "mode" "!SF")))
+ "atom-fmul-5c")
+
+;; Except dppd/dpps, 4 cycle if mulss
+(define_insn_reservation "atom_ssemul_2" 4
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "ssemul")
+ (eq_attr "mode" "SF")))
+ "atom-fmul-4c")
+
+(define_insn_reservation "atom_ssecmp" 1
+ (and (eq_attr "cpu" "atom")
+ (eq_attr "type" "ssecmp"))
+ "atom-simple-either")
+
+(define_insn_reservation "atom_ssecomi" 10
+ (and (eq_attr "cpu" "atom")
+ (eq_attr "type" "ssecomi"))
+ "atom-complex, atom-all-eu*9")
+
+;; no memory and cvtpi2ps, cvtps2pi, cvttps2pi
+(define_insn_reservation "atom_ssecvt" 5
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "ssecvt")
+ (ior (and (match_operand:V2SI 0 "register_operand")
+ (match_operand:V4SF 1 "register_operand"))
+ (and (match_operand:V4SF 0 "register_operand")
+ (match_operand:V2SI 1 "register_operand")))))
+ "atom-fadd-5c")
+
+;; memory and cvtpi2ps, cvtps2pi, cvttps2pi
+(define_insn_reservation "atom_ssecvt_2" 5
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "ssecvt")
+ (ior (and (match_operand:V2SI 0 "register_operand")
+ (match_operand:V4SF 1 "memory_operand"))
+ (and (match_operand:V4SF 0 "register_operand")
+ (match_operand:V2SI 1 "memory_operand")))))
+ "atom-dual-5c")
+
+;; otherwise. 7 cycles average for cvtss2sd
+(define_insn_reservation "atom_ssecvt_3" 7
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "ssecvt")
+ (not (ior (and (match_operand:V2SI 0 "register_operand")
+ (match_operand:V4SF 1 "nonimmediate_operand"))
+ (and (match_operand:V4SF 0 "register_operand")
+ (match_operand:V2SI 1 "nonimmediate_operand"))))))
+ "atom-complex, atom-all-eu*6")
+
+;; memory and cvtsi2sd
+(define_insn_reservation "atom_sseicvt" 5
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "sseicvt")
+ (and (match_operand:V2DF 0 "register_operand")
+ (match_operand:SI 1 "memory_operand"))))
+ "atom-dual-5c")
+
+;; otherwise. 8 cycles average for cvtsd2si
+(define_insn_reservation "atom_sseicvt_2" 8
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "sseicvt")
+ (not (and (match_operand:V2DF 0 "register_operand")
+ (match_operand:SI 1 "memory_operand")))))
+ "atom-complex, atom-all-eu*7")
+
+(define_insn_reservation "atom_ssediv" 62
+ (and (eq_attr "cpu" "atom")
+ (eq_attr "type" "ssediv"))
+ "atom-complex, atom-all-eu*12, nothing*49")
+
+;; simple for fmov
+(define_insn_reservation "atom_fmov" 1
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "fmov")
+ (eq_attr "memory" "none")))
+ "atom-simple-either")
+
+;; simple for fmov
+(define_insn_reservation "atom_fmov_mem" 1
+ (and (eq_attr "cpu" "atom")
+ (and (eq_attr "type" "fmov")
+ (eq_attr "memory" "!none")))
+ "atom-simple-either")
+
+;; Define bypass here
+
+;; There will be no stall from lea to non-mem EX insns
+(define_bypass 0 "atom_lea"
+ "atom_alu_carry,
+ atom_alu,atom_alu1,atom_negnot,atom_imov,atom_imovx,
+ atom_incdec, atom_setcc, atom_icmov, atom_pop")
+
+(define_bypass 0 "atom_lea"
+ "atom_alu_mem, atom_alu_carry_mem, atom_alu1_mem,
+ atom_imovx_mem, atom_imovx_2_mem,
+ atom_imov_mem, atom_icmov_mem, atom_fmov_mem"
+ "!ix86_agi_dependent")
+
+;; There will be 3 cycles stall from EX insns to AGAN insns LEA
+(define_bypass 4 "atom_alu_carry,
+ atom_alu,atom_alu1,atom_negnot,atom_imov,atom_imovx,
+ atom_incdec,atom_ishift,atom_ishift1,atom_rotate,
+ atom_rotate1, atom_setcc, atom_icmov, atom_pop,
+ atom_alu_mem, atom_alu_carry_mem, atom_alu1_mem,
+ atom_imovx_mem, atom_imovx_2_mem,
+ atom_imov_mem, atom_icmov_mem, atom_fmov_mem"
+ "atom_lea")
+
+;; There will be 3 cycles stall from EX insns to insns need addr calculation
+(define_bypass 4 "atom_alu_carry,
+ atom_alu,atom_alu1,atom_negnot,atom_imov,atom_imovx,
+ atom_incdec,atom_ishift,atom_ishift1,atom_rotate,
+ atom_rotate1, atom_setcc, atom_icmov, atom_pop,
+ atom_imovx_mem, atom_imovx_2_mem,
+ atom_alu_mem, atom_alu_carry_mem, atom_alu1_mem,
+ atom_imov_mem, atom_icmov_mem, atom_fmov_mem"
+ "atom_alu_mem, atom_alu_carry_mem, atom_alu1_mem,
+ atom_negnot_mem, atom_imov_mem, atom_incdec_mem,
+ atom_imovx_mem, atom_imovx_2_mem,
+ atom_imul_mem, atom_icmp_mem,
+ atom_test_mem, atom_icmov_mem, atom_sselog_mem,
+ atom_sselog1_mem, atom_fmov_mem, atom_sseadd_mem,
+ atom_ishift_mem, atom_ishift1_mem,
+ atom_rotate_mem, atom_rotate1_mem"
+ "ix86_agi_dependent")
+
+;; Stall from imul to lea is 8 cycles.
+(define_bypass 9 "atom_imul, atom_imul_mem" "atom_lea")
+
+;; Stall from imul to memory address is 8 cycles.
+(define_bypass 9 "atom_imul, atom_imul_mem"
+ "atom_alu_mem, atom_alu_carry_mem, atom_alu1_mem,
+ atom_negnot_mem, atom_imov_mem, atom_incdec_mem,
+ atom_ishift_mem, atom_ishift1_mem, atom_rotate_mem,
+ atom_rotate1_mem, atom_imul_mem, atom_icmp_mem,
+ atom_test_mem, atom_icmov_mem, atom_sselog_mem,
+ atom_sselog1_mem, atom_fmov_mem, atom_sseadd_mem"
+ "ix86_agi_dependent")
+
+;; There will be 0 cycle stall from cmp/test to jcc
+
+;; There will be 1 cycle stall from flag producer to cmov and adc/sbb
+(define_bypass 2 "atom_icmp, atom_test, atom_alu, atom_alu_carry,
+ atom_alu1, atom_negnot, atom_incdec, atom_ishift,
+ atom_ishift1, atom_rotate, atom_rotate1"
+ "atom_icmov, atom_alu_carry")
+
+;; lea to shift count stall is 2 cycles
+(define_bypass 3 "atom_lea"
+ "atom_ishift, atom_ishift1, atom_rotate, atom_rotate1,
+ atom_ishift_mem, atom_ishift1_mem,
+ atom_rotate_mem, atom_rotate1_mem"
+ "ix86_dep_by_shift_count")
+
+;; lea to shift source stall is 1 cycle
+(define_bypass 2 "atom_lea"
+ "atom_ishift, atom_ishift1, atom_rotate, atom_rotate1"
+ "!ix86_dep_by_shift_count")
+
+;; non-lea to shift count stall is 1 cycle
+(define_bypass 2 "atom_alu_carry,
+ atom_alu,atom_alu1,atom_negnot,atom_imov,atom_imovx,
+ atom_incdec,atom_ishift,atom_ishift1,atom_rotate,
+ atom_rotate1, atom_setcc, atom_icmov, atom_pop,
+ atom_alu_mem, atom_alu_carry_mem, atom_alu1_mem,
+ atom_imovx_mem, atom_imovx_2_mem,
+ atom_imov_mem, atom_icmov_mem, atom_fmov_mem"
+ "atom_ishift, atom_ishift1, atom_rotate, atom_rotate1,
+ atom_ishift_mem, atom_ishift1_mem,
+ atom_rotate_mem, atom_rotate1_mem"
+ "ix86_dep_by_shift_count")
diff --git a/gcc-4.4.3/gcc/config/i386/cpuid.h b/gcc-4.4.3/gcc/config/i386/cpuid.h
index b5258652e..003c202f0 100644
--- a/gcc-4.4.3/gcc/config/i386/cpuid.h
+++ b/gcc-4.4.3/gcc/config/i386/cpuid.h
@@ -29,6 +29,7 @@
#define bit_CMPXCHG16B (1 << 13)
#define bit_SSE4_1 (1 << 19)
#define bit_SSE4_2 (1 << 20)
+#define bit_MOVBE (1 << 22)
#define bit_POPCNT (1 << 23)
#define bit_AES (1 << 25)
#define bit_XSAVE (1 << 26)
@@ -46,6 +47,7 @@
/* Extended Features */
/* %ecx */
#define bit_LAHF_LM (1 << 0)
+#define bit_LWP (1 << 15)
#define bit_SSE4a (1 << 6)
#define bit_SSE5 (1 << 11)
diff --git a/gcc-4.4.3/gcc/config/i386/cygming.h b/gcc-4.4.3/gcc/config/i386/cygming.h
index 4f508a776..39650b107 100644
--- a/gcc-4.4.3/gcc/config/i386/cygming.h
+++ b/gcc-4.4.3/gcc/config/i386/cygming.h
@@ -34,7 +34,7 @@ along with GCC; see the file COPYING3. If not see
#endif
#undef TARGET_64BIT_MS_ABI
-#define TARGET_64BIT_MS_ABI (!cfun ? DEFAULT_ABI == MS_ABI : TARGET_64BIT && cfun->machine->call_abi == MS_ABI)
+#define TARGET_64BIT_MS_ABI (!cfun ? ix86_abi == MS_ABI : TARGET_64BIT && cfun->machine->call_abi == MS_ABI)
#undef DEFAULT_ABI
#define DEFAULT_ABI (TARGET_64BIT ? MS_ABI : SYSV_ABI)
@@ -202,7 +202,7 @@ do { \
#define CHECK_STACK_LIMIT 4000
#undef STACK_BOUNDARY
-#define STACK_BOUNDARY (DEFAULT_ABI == MS_ABI ? 128 : BITS_PER_WORD)
+#define STACK_BOUNDARY (ix86_abi == MS_ABI ? 128 : BITS_PER_WORD)
/* By default, target has a 80387, uses IEEE compatible arithmetic,
returns float values in the 387 and needs stack probes.
diff --git a/gcc-4.4.3/gcc/config/i386/driver-i386.c b/gcc-4.4.3/gcc/config/i386/driver-i386.c
index 9aa33d27c..c506b2bc3 100644
--- a/gcc-4.4.3/gcc/config/i386/driver-i386.c
+++ b/gcc-4.4.3/gcc/config/i386/driver-i386.c
@@ -378,6 +378,7 @@ const char *host_detect_local_cpu (int argc, const char **argv)
/* Extended features */
unsigned int has_lahf_lm = 0, has_sse4a = 0;
unsigned int has_longmode = 0, has_3dnowp = 0, has_3dnow = 0;
+ unsigned int has_movbe = 0;
unsigned int has_sse4_1 = 0, has_sse4_2 = 0;
unsigned int has_popcnt = 0, has_aes = 0, has_avx = 0;
unsigned int has_pclmul = 0;
@@ -398,9 +399,22 @@ const char *host_detect_local_cpu (int argc, const char **argv)
__cpuid (1, eax, ebx, ecx, edx);
- /* We don't care for extended family. */
model = (eax >> 4) & 0x0f;
family = (eax >> 8) & 0x0f;
+ if (vendor == SIG_INTEL)
+ {
+ unsigned int extended_model, extended_family;
+
+ extended_model = (eax >> 12) & 0xf0;
+ extended_family = (eax >> 20) & 0xff;
+ if (family == 0x0f)
+ {
+ family += extended_family;
+ model += extended_model;
+ }
+ else if (family == 0x06)
+ model += extended_model;
+ }
has_sse3 = ecx & bit_SSE3;
has_ssse3 = ecx & bit_SSSE3;
@@ -408,6 +422,7 @@ const char *host_detect_local_cpu (int argc, const char **argv)
has_sse4_2 = ecx & bit_SSE4_2;
has_avx = ecx & bit_AVX;
has_cmpxchg16b = ecx & bit_CMPXCHG16B;
+ has_movbe = ecx & bit_MOVBE;
has_popcnt = ecx & bit_POPCNT;
has_aes = ecx & bit_AES;
has_pclmul = ecx & bit_PCLMUL;
@@ -505,8 +520,8 @@ const char *host_detect_local_cpu (int argc, const char **argv)
break;
case PROCESSOR_PENTIUMPRO:
if (has_longmode)
- /* It is Core 2 Duo. */
- cpu = "core2";
+ /* It is Core 2 or Atom. */
+ cpu = (model == 28 || model == 38) ? "atom" : "core2";
else if (arch)
{
if (has_sse3)
@@ -597,6 +612,8 @@ const char *host_detect_local_cpu (int argc, const char **argv)
options = concat (options, "-mcx16 ", NULL);
if (has_lahf_lm)
options = concat (options, "-msahf ", NULL);
+ if (has_movbe)
+ options = concat (options, "-mmovbe", NULL);
if (has_aes)
options = concat (options, "-maes ", NULL);
if (has_pclmul)
diff --git a/gcc-4.4.3/gcc/config/i386/i386-c.c b/gcc-4.4.3/gcc/config/i386/i386-c.c
index 3d17c104e..1bb394542 100644
--- a/gcc-4.4.3/gcc/config/i386/i386-c.c
+++ b/gcc-4.4.3/gcc/config/i386/i386-c.c
@@ -119,6 +119,10 @@ ix86_target_macros_internal (int isa_flag,
def_or_undef (parse_in, "__core2");
def_or_undef (parse_in, "__core2__");
break;
+ case PROCESSOR_ATOM:
+ def_or_undef (parse_in, "__atom");
+ def_or_undef (parse_in, "__atom__");
+ break;
/* use PROCESSOR_max to not set/unset the arch macro. */
case PROCESSOR_max:
break;
@@ -187,6 +191,9 @@ ix86_target_macros_internal (int isa_flag,
case PROCESSOR_CORE2:
def_or_undef (parse_in, "__tune_core2__");
break;
+ case PROCESSOR_ATOM:
+ def_or_undef (parse_in, "__tune_atom__");
+ break;
case PROCESSOR_GENERIC32:
case PROCESSOR_GENERIC64:
break;
@@ -225,6 +232,8 @@ ix86_target_macros_internal (int isa_flag,
def_or_undef (parse_in, "__SSE4A__");
if (isa_flag & OPTION_MASK_ISA_SSE5)
def_or_undef (parse_in, "__SSE5__");
+ if (isa_flag & OPTION_MASK_ISA_LWP)
+ def_or_undef (parse_in, "__LWP__");
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))
diff --git a/gcc-4.4.3/gcc/config/i386/i386-protos.h b/gcc-4.4.3/gcc/config/i386/i386-protos.h
index 4b0e2c01c..96e01ea49 100644
--- a/gcc-4.4.3/gcc/config/i386/i386-protos.h
+++ b/gcc-4.4.3/gcc/config/i386/i386-protos.h
@@ -86,6 +86,9 @@ extern void ix86_fixup_binary_operands_no_copy (enum rtx_code,
extern void ix86_expand_binary_operator (enum rtx_code,
enum machine_mode, rtx[]);
extern int ix86_binary_operator_ok (enum rtx_code, enum machine_mode, rtx[]);
+extern bool ix86_lea_for_add_ok (enum rtx_code, rtx, rtx[]);
+extern bool ix86_dep_by_shift_count (const_rtx set_insn, const_rtx use_insn);
+extern bool ix86_agi_dependent (rtx set_insn, rtx use_insn);
extern void ix86_expand_unary_operator (enum rtx_code, enum machine_mode,
rtx[]);
extern rtx ix86_build_const_vector (enum machine_mode, bool, rtx);
@@ -140,9 +143,8 @@ extern int ix86_function_arg_boundary (enum machine_mode, tree);
extern bool ix86_sol10_return_in_memory (const_tree,const_tree);
extern rtx ix86_force_to_memory (enum machine_mode, rtx);
extern void ix86_free_from_memory (enum machine_mode);
-extern int ix86_cfun_abi (void);
-extern int ix86_function_abi (const_tree);
-extern int ix86_function_type_abi (const_tree);
+extern enum calling_abi ix86_cfun_abi (void);
+extern enum calling_abi 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);
diff --git a/gcc-4.4.3/gcc/config/i386/i386.c b/gcc-4.4.3/gcc/config/i386/i386.c
index 350b214ed..fa148be65 100644
--- a/gcc-4.4.3/gcc/config/i386/i386.c
+++ b/gcc-4.4.3/gcc/config/i386/i386.c
@@ -1036,6 +1036,79 @@ struct processor_costs core2_cost = {
1, /* cond_not_taken_branch_cost. */
};
+static const
+struct processor_costs atom_cost = {
+ COSTS_N_INSNS (1), /* cost of an add instruction */
+ COSTS_N_INSNS (1) + 1, /* cost of a lea instruction */
+ COSTS_N_INSNS (1), /* variable shift costs */
+ COSTS_N_INSNS (1), /* constant shift costs */
+ {COSTS_N_INSNS (3), /* cost of starting multiply for QI */
+ COSTS_N_INSNS (4), /* HI */
+ COSTS_N_INSNS (3), /* SI */
+ COSTS_N_INSNS (4), /* DI */
+ COSTS_N_INSNS (2)}, /* other */
+ 0, /* cost of multiply per each bit set */
+ {COSTS_N_INSNS (18), /* cost of a divide/mod for QI */
+ COSTS_N_INSNS (26), /* HI */
+ COSTS_N_INSNS (42), /* SI */
+ COSTS_N_INSNS (74), /* DI */
+ COSTS_N_INSNS (74)}, /* other */
+ COSTS_N_INSNS (1), /* cost of movsx */
+ COSTS_N_INSNS (1), /* cost of movzx */
+ 8, /* "large" insn */
+ 17, /* MOVE_RATIO */
+ 2, /* cost for loading QImode using movzbl */
+ {4, 4, 4}, /* cost of loading integer registers
+ in QImode, HImode and SImode.
+ Relative to reg-reg move (2). */
+ {4, 4, 4}, /* cost of storing integer registers */
+ 4, /* cost of reg,reg fld/fst */
+ {12, 12, 12}, /* cost of loading fp registers
+ in SFmode, DFmode and XFmode */
+ {6, 6, 8}, /* cost of storing fp registers
+ in SFmode, DFmode and XFmode */
+ 2, /* cost of moving MMX register */
+ {8, 8}, /* cost of loading MMX registers
+ in SImode and DImode */
+ {8, 8}, /* cost of storing MMX registers
+ in SImode and DImode */
+ 2, /* cost of moving SSE register */
+ {8, 8, 8}, /* cost of loading SSE registers
+ in SImode, DImode and TImode */
+ {8, 8, 8}, /* cost of storing SSE registers
+ in SImode, DImode and TImode */
+ 5, /* MMX or SSE register to integer */
+ 32, /* size of l1 cache. */
+ 256, /* size of l2 cache. */
+ 64, /* size of prefetch block */
+ 6, /* number of parallel prefetches */
+ 3, /* Branch cost */
+ COSTS_N_INSNS (8), /* cost of FADD and FSUB insns. */
+ COSTS_N_INSNS (8), /* cost of FMUL instruction. */
+ COSTS_N_INSNS (20), /* cost of FDIV instruction. */
+ COSTS_N_INSNS (8), /* cost of FABS instruction. */
+ COSTS_N_INSNS (8), /* cost of FCHS instruction. */
+ COSTS_N_INSNS (40), /* cost of FSQRT instruction. */
+ {{libcall, {{11, loop}, {-1, rep_prefix_4_byte}}},
+ {libcall, {{32, loop}, {64, rep_prefix_4_byte},
+ {8192, rep_prefix_8_byte}, {-1, libcall}}}},
+ {{libcall, {{8, loop}, {15, unrolled_loop},
+ {2048, rep_prefix_4_byte}, {-1, libcall}}},
+ {libcall, {{24, loop}, {32, unrolled_loop},
+ {8192, rep_prefix_8_byte}, {-1, libcall}}}},
+ 1, /* scalar_stmt_cost. */
+ 1, /* scalar load_cost. */
+ 1, /* scalar_store_cost. */
+ 1, /* vec_stmt_cost. */
+ 1, /* vec_to_scalar_cost. */
+ 1, /* scalar_to_vec_cost. */
+ 1, /* vec_align_load_cost. */
+ 2, /* vec_unalign_load_cost. */
+ 1, /* vec_store_cost. */
+ 3, /* cond_taken_branch_cost. */
+ 1, /* cond_not_taken_branch_cost. */
+};
+
/* Generic64 should produce code tuned for Nocona and K8. */
static const
struct processor_costs generic64_cost = {
@@ -1194,6 +1267,7 @@ const struct processor_costs *ix86_cost = &pentium_cost;
#define m_PENT4 (1<<PROCESSOR_PENTIUM4)
#define m_NOCONA (1<<PROCESSOR_NOCONA)
#define m_CORE2 (1<<PROCESSOR_CORE2)
+#define m_ATOM (1<<PROCESSOR_ATOM)
#define m_GEODE (1<<PROCESSOR_GEODE)
#define m_K6 (1<<PROCESSOR_K6)
@@ -1231,10 +1305,11 @@ static unsigned int initial_ix86_tune_features[X86_TUNE_LAST] = {
m_486 | m_PENT,
/* X86_TUNE_UNROLL_STRLEN */
- m_486 | m_PENT | m_PPRO | m_AMD_MULTIPLE | m_K6 | m_CORE2 | m_GENERIC,
+ m_486 | m_PENT | m_ATOM | m_PPRO | m_AMD_MULTIPLE | m_K6
+ | m_CORE2 | m_GENERIC,
/* X86_TUNE_DEEP_BRANCH_PREDICTION */
- m_PPRO | m_K6_GEODE | m_AMD_MULTIPLE | m_PENT4 | m_GENERIC,
+ m_ATOM | m_PPRO | m_K6_GEODE | m_AMD_MULTIPLE | m_PENT4 | m_GENERIC,
/* X86_TUNE_BRANCH_PREDICTION_HINTS: Branch hints were put in P4 based
on simulation result. But after P4 was made, no performance benefit
@@ -1246,12 +1321,12 @@ static unsigned int initial_ix86_tune_features[X86_TUNE_LAST] = {
~m_386,
/* X86_TUNE_USE_SAHF */
- m_PPRO | m_K6_GEODE | m_K8 | m_AMDFAM10 | m_PENT4
+ m_ATOM | m_PPRO | m_K6_GEODE | m_K8 | m_AMDFAM10 | m_PENT4
| m_NOCONA | m_CORE2 | m_GENERIC,
/* X86_TUNE_MOVX: Enable to zero extend integer registers to avoid
partial dependencies. */
- m_AMD_MULTIPLE | m_PPRO | m_PENT4 | m_NOCONA
+ m_AMD_MULTIPLE | m_ATOM | m_PPRO | m_PENT4 | m_NOCONA
| m_CORE2 | m_GENERIC | m_GEODE /* m_386 | m_K6 */,
/* X86_TUNE_PARTIAL_REG_STALL: We probably ought to watch for partial
@@ -1271,13 +1346,13 @@ static unsigned int initial_ix86_tune_features[X86_TUNE_LAST] = {
m_386 | m_486 | m_K6_GEODE,
/* X86_TUNE_USE_SIMODE_FIOP */
- ~(m_PPRO | m_AMD_MULTIPLE | m_PENT | m_CORE2 | m_GENERIC),
+ ~(m_PPRO | m_AMD_MULTIPLE | m_PENT | m_ATOM | m_CORE2 | m_GENERIC),
/* X86_TUNE_USE_MOV0 */
m_K6,
/* X86_TUNE_USE_CLTD */
- ~(m_PENT | m_K6 | m_CORE2 | m_GENERIC),
+ ~(m_PENT | m_ATOM | m_K6 | m_CORE2 | m_GENERIC),
/* X86_TUNE_USE_XCHGB: Use xchgb %rh,%rl instead of rolw/rorw $8,rx. */
m_PENT4,
@@ -1292,8 +1367,8 @@ static unsigned int initial_ix86_tune_features[X86_TUNE_LAST] = {
~(m_PENT | m_PPRO),
/* X86_TUNE_PROMOTE_QIMODE */
- m_K6_GEODE | m_PENT | m_386 | m_486 | m_AMD_MULTIPLE | m_CORE2
- | m_GENERIC /* | m_PENT4 ? */,
+ m_K6_GEODE | m_PENT | m_ATOM | m_386 | m_486 | m_AMD_MULTIPLE
+ | m_CORE2 | m_GENERIC /* | m_PENT4 ? */,
/* X86_TUNE_FAST_PREFIX */
~(m_PENT | m_486 | m_386),
@@ -1317,26 +1392,28 @@ static unsigned int initial_ix86_tune_features[X86_TUNE_LAST] = {
m_PPRO,
/* X86_TUNE_ADD_ESP_4: Enable if add/sub is preferred over 1/2 push/pop. */
- m_AMD_MULTIPLE | m_K6_GEODE | m_PENT4 | m_NOCONA | m_CORE2 | m_GENERIC,
+ m_ATOM | m_AMD_MULTIPLE | m_K6_GEODE | m_PENT4 | m_NOCONA
+ | m_CORE2 | m_GENERIC,
/* X86_TUNE_ADD_ESP_8 */
- m_AMD_MULTIPLE | m_PPRO | m_K6_GEODE | m_386
+ m_AMD_MULTIPLE | m_ATOM | m_PPRO | m_K6_GEODE | m_386
| m_486 | m_PENT4 | m_NOCONA | m_CORE2 | m_GENERIC,
/* X86_TUNE_SUB_ESP_4 */
- m_AMD_MULTIPLE | m_PPRO | m_PENT4 | m_NOCONA | m_CORE2 | m_GENERIC,
+ m_AMD_MULTIPLE | m_ATOM | m_PPRO | m_PENT4 | m_NOCONA | m_CORE2
+ | m_GENERIC,
/* X86_TUNE_SUB_ESP_8 */
- m_AMD_MULTIPLE | m_PPRO | m_386 | m_486
+ m_AMD_MULTIPLE | m_ATOM | m_PPRO | m_386 | m_486
| m_PENT4 | m_NOCONA | m_CORE2 | m_GENERIC,
/* X86_TUNE_INTEGER_DFMODE_MOVES: Enable if integer moves are preferred
for DFmode copies */
- ~(m_AMD_MULTIPLE | m_PENT4 | m_NOCONA | m_PPRO | m_CORE2
+ ~(m_AMD_MULTIPLE | m_ATOM | m_PENT4 | m_NOCONA | m_PPRO | m_CORE2
| m_GENERIC | m_GEODE),
/* X86_TUNE_PARTIAL_REG_DEPENDENCY */
- m_AMD_MULTIPLE | m_PENT4 | m_NOCONA | m_CORE2 | m_GENERIC,
+ m_AMD_MULTIPLE | m_ATOM | m_PENT4 | m_NOCONA | m_CORE2 | m_GENERIC,
/* X86_TUNE_SSE_PARTIAL_REG_DEPENDENCY: In the Generic model we have a
conflict here in between PPro/Pentium4 based chips that thread 128bit
@@ -1347,7 +1424,8 @@ static unsigned int initial_ix86_tune_features[X86_TUNE_LAST] = {
shows that disabling this option on P4 brings over 20% SPECfp regression,
while enabling it on K8 brings roughly 2.4% regression that can be partly
masked by careful scheduling of moves. */
- m_PENT4 | m_NOCONA | m_PPRO | m_CORE2 | m_GENERIC | m_AMDFAM10,
+ m_ATOM | m_PENT4 | m_NOCONA | m_PPRO | m_CORE2 | m_GENERIC
+ | m_AMDFAM10,
/* X86_TUNE_SSE_UNALIGNED_MOVE_OPTIMAL */
m_AMDFAM10,
@@ -1365,13 +1443,13 @@ static unsigned int initial_ix86_tune_features[X86_TUNE_LAST] = {
m_PPRO | m_PENT4 | m_NOCONA,
/* X86_TUNE_MEMORY_MISMATCH_STALL */
- m_AMD_MULTIPLE | m_PENT4 | m_NOCONA | m_CORE2 | m_GENERIC,
+ m_AMD_MULTIPLE | m_ATOM | m_PENT4 | m_NOCONA | m_CORE2 | m_GENERIC,
/* X86_TUNE_PROLOGUE_USING_MOVE */
- m_ATHLON_K8 | m_PPRO | m_CORE2 | m_GENERIC,
+ m_ATHLON_K8 | m_ATOM | m_PPRO | m_CORE2 | m_GENERIC,
/* X86_TUNE_EPILOGUE_USING_MOVE */
- m_ATHLON_K8 | m_PPRO | m_CORE2 | m_GENERIC,
+ m_ATHLON_K8 | m_ATOM | m_PPRO | m_CORE2 | m_GENERIC,
/* X86_TUNE_SHIFT1 */
~m_486,
@@ -1387,22 +1465,25 @@ static unsigned int initial_ix86_tune_features[X86_TUNE_LAST] = {
/* X86_TUNE_FOUR_JUMP_LIMIT: Some CPU cores are not able to predict more
than 4 branch instructions in the 16 byte window. */
- m_PPRO | m_AMD_MULTIPLE | m_PENT4 | m_NOCONA | m_CORE2 | m_GENERIC,
+ m_ATOM | m_PPRO | m_AMD_MULTIPLE | m_PENT4 | m_NOCONA | m_CORE2
+ | m_GENERIC,
/* X86_TUNE_SCHEDULE */
- m_PPRO | m_AMD_MULTIPLE | m_K6_GEODE | m_PENT | m_CORE2 | m_GENERIC,
+ m_PPRO | m_AMD_MULTIPLE | m_K6_GEODE | m_PENT | m_ATOM | m_CORE2
+ | m_GENERIC,
/* X86_TUNE_USE_BT */
- m_AMD_MULTIPLE | m_CORE2 | m_GENERIC,
+ m_AMD_MULTIPLE | m_ATOM | m_CORE2 | m_GENERIC,
/* X86_TUNE_USE_INCDEC */
- ~(m_PENT4 | m_NOCONA | m_GENERIC),
+ ~(m_PENT4 | m_NOCONA | m_GENERIC | m_ATOM),
/* X86_TUNE_PAD_RETURNS */
m_AMD_MULTIPLE | m_CORE2 | m_GENERIC,
/* X86_TUNE_EXT_80387_CONSTANTS */
- m_K6_GEODE | m_ATHLON_K8 | m_PENT4 | m_NOCONA | m_PPRO | m_CORE2 | m_GENERIC,
+ m_K6_GEODE | m_ATHLON_K8 | m_ATOM | m_PENT4 | m_NOCONA | m_PPRO
+ | m_CORE2 | m_GENERIC,
/* X86_TUNE_SHORTEN_X87_SSE */
~m_K8,
@@ -1447,6 +1528,10 @@ static unsigned int initial_ix86_tune_features[X86_TUNE_LAST] = {
with a subsequent conditional jump instruction into a single
compare-and-branch uop. */
m_CORE2,
+
+ /* X86_TUNE_OPT_AGU: Optimize for Address Generation Unit. This flag
+ will impact LEA instruction selection. */
+ m_ATOM,
};
/* Feature tests against the various architecture variations. */
@@ -1472,10 +1557,11 @@ static unsigned int initial_ix86_arch_features[X86_ARCH_LAST] = {
};
static const unsigned int x86_accumulate_outgoing_args
- = m_AMD_MULTIPLE | m_PENT4 | m_NOCONA | m_PPRO | m_CORE2 | m_GENERIC;
+ = m_AMD_MULTIPLE | m_ATOM | m_PENT4 | m_NOCONA | m_PPRO | m_CORE2
+ | m_GENERIC;
static const unsigned int x86_arch_always_fancy_math_387
- = m_PENT | m_PPRO | m_AMD_MULTIPLE | m_PENT4
+ = m_PENT | m_ATOM | m_PPRO | m_AMD_MULTIPLE | m_PENT4
| m_NOCONA | m_CORE2 | m_GENERIC;
static enum stringop_alg stringop_alg = no_stringop;
@@ -1743,6 +1829,9 @@ static unsigned int ix86_default_incoming_stack_boundary;
/* Alignment for incoming stack boundary in bits. */
unsigned int ix86_incoming_stack_boundary;
+/* The abi used by target. */
+enum calling_abi ix86_abi;
+
/* Values 1-5: see jump.c */
int ix86_branch_cost;
@@ -1818,6 +1907,9 @@ static bool ix86_valid_target_attribute_p (tree, tree, tree, int);
static bool ix86_valid_target_attribute_inner_p (tree, char *[]);
static bool ix86_can_inline_p (tree, tree);
static void ix86_set_current_function (tree);
+static unsigned int ix86_minimum_incoming_stack_boundary (bool);
+
+static enum calling_abi ix86_function_abi (const_tree);
/* The svr4 ABI for the i386 says that records and unions are returned
@@ -1868,6 +1960,8 @@ static int ix86_isa_flags_explicit;
(OPTION_MASK_ISA_SSE4A | OPTION_MASK_ISA_SSE3_SET)
#define OPTION_MASK_ISA_SSE5_SET \
(OPTION_MASK_ISA_SSE5 | OPTION_MASK_ISA_SSE4A_SET)
+#define OPTION_MASK_ISA_LWP_SET \
+ OPTION_MASK_ISA_LWP
/* AES and PCLMUL need SSE2 because they use xmm registers */
#define OPTION_MASK_ISA_AES_SET \
@@ -1877,9 +1971,11 @@ static int ix86_isa_flags_explicit;
#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 OPTION_MASK_ISA_MOVBE_SET OPTION_MASK_ISA_MOVBE
/* Define a set of ISAs which aren't available when a given ISA is
disabled. MMX and SSE ISAs are handled separately. */
@@ -1915,12 +2011,14 @@ 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_LWP_UNSET OPTION_MASK_ISA_LWP
#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
+#define OPTION_MASK_ISA_MOVBE_UNSET OPTION_MASK_ISA_MOVBE
/* Vectorization library interface and handlers. */
tree (*ix86_veclib_handler)(enum built_in_function, tree, tree) = NULL;
@@ -1953,7 +2051,8 @@ static const struct ptt processor_target_table[PROCESSOR_max] =
{&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}
+ {&amdfam10_cost, 32, 24, 32, 7, 32},
+ {&atom_cost, 16, 7, 16, 7, 16}
};
static const char *const cpu_names[TARGET_CPU_DEFAULT_max] =
@@ -1971,6 +2070,7 @@ static const char *const cpu_names[TARGET_CPU_DEFAULT_max] =
"prescott",
"nocona",
"core2",
+ "atom",
"geode",
"k6",
"k6-2",
@@ -2157,6 +2257,19 @@ ix86_handle_option (size_t code, const char *arg ATTRIBUTE_UNUSED, int value)
}
return true;
+ case OPT_mlwp:
+ if (value)
+ {
+ ix86_isa_flags |= OPTION_MASK_ISA_LWP_SET;
+ ix86_isa_flags_explicit |= OPTION_MASK_ISA_LWP_SET;
+ }
+ else
+ {
+ ix86_isa_flags &= ~OPTION_MASK_ISA_LWP_UNSET;
+ ix86_isa_flags_explicit |= OPTION_MASK_ISA_LWP_UNSET;
+ }
+ return true;
+
case OPT_mabm:
if (value)
{
@@ -2209,6 +2322,19 @@ ix86_handle_option (size_t code, const char *arg ATTRIBUTE_UNUSED, int value)
}
return true;
+ case OPT_mmovbe:
+ if (value)
+ {
+ ix86_isa_flags |= OPTION_MASK_ISA_MOVBE_SET;
+ ix86_isa_flags_explicit |= OPTION_MASK_ISA_MOVBE_SET;
+ }
+ else
+ {
+ ix86_isa_flags &= ~OPTION_MASK_ISA_MOVBE_UNSET;
+ ix86_isa_flags_explicit |= OPTION_MASK_ISA_MOVBE_UNSET;
+ }
+ return true;
+
case OPT_maes:
if (value)
{
@@ -2259,6 +2385,7 @@ ix86_target_string (int isa, int flags, const char *arch, const char *tune,
{
{ "-m64", OPTION_MASK_ISA_64BIT },
{ "-msse5", OPTION_MASK_ISA_SSE5 },
+ { "-mlwp", OPTION_MASK_ISA_LWP },
{ "-msse4a", OPTION_MASK_ISA_SSE4A },
{ "-msse4.2", OPTION_MASK_ISA_SSE4_2 },
{ "-msse4.1", OPTION_MASK_ISA_SSE4_1 },
@@ -2271,6 +2398,7 @@ ix86_target_string (int isa, int flags, const char *arch, const char *tune,
{ "-mmmx", OPTION_MASK_ISA_MMX },
{ "-mabm", OPTION_MASK_ISA_ABM },
{ "-mpopcnt", OPTION_MASK_ISA_POPCNT },
+ { "-mmovbe", OPTION_MASK_ISA_MOVBE },
{ "-maes", OPTION_MASK_ISA_AES },
{ "-mpclmul", OPTION_MASK_ISA_PCLMUL },
};
@@ -2488,7 +2616,9 @@ override_options (bool main_args_p)
PTA_AES = 1 << 17,
PTA_PCLMUL = 1 << 18,
PTA_AVX = 1 << 19,
- PTA_FMA = 1 << 20
+ PTA_FMA = 1 << 20,
+ PTA_LWP = 1 << 21,
+ PTA_MOVBE = 1 << 22
};
static struct pta
@@ -2530,6 +2660,9 @@ override_options (bool main_args_p)
{"core2", PROCESSOR_CORE2, CPU_CORE2,
PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3
| PTA_SSSE3 | PTA_CX16},
+ {"atom", PROCESSOR_ATOM, CPU_ATOM,
+ PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3
+ | PTA_SSSE3 | PTA_CX16 | PTA_MOVBE},
{"geode", PROCESSOR_GEODE, CPU_GEODE,
PTA_MMX | PTA_3DNOW | PTA_3DNOW_A |PTA_PREFETCH_SSE},
{"k6", PROCESSOR_K6, CPU_K6, PTA_MMX},
@@ -2717,6 +2850,20 @@ override_options (bool main_args_p)
error ("bad value (%s) for %sarch=%s %s",
ix86_arch_string, prefix, suffix, sw);
+ /* Validate -mabi= value. */
+ if (ix86_abi_string)
+ {
+ if (strcmp (ix86_abi_string, "sysv") == 0)
+ ix86_abi = SYSV_ABI;
+ else if (strcmp (ix86_abi_string, "ms") == 0)
+ ix86_abi = MS_ABI;
+ else
+ error ("unknown ABI (%s) for %sabi=%s %s",
+ ix86_abi_string, prefix, suffix, sw);
+ }
+ else
+ ix86_abi = DEFAULT_ABI;
+
if (ix86_cmodel_string != 0)
{
if (!strcmp (ix86_cmodel_string, "small"))
@@ -2817,6 +2964,9 @@ override_options (bool main_args_p)
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_LWP
+ && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_LWP))
+ ix86_isa_flags |= OPTION_MASK_ISA_LWP;
if (processor_alias_table[i].flags & PTA_ABM
&& !(ix86_isa_flags_explicit & OPTION_MASK_ISA_ABM))
ix86_isa_flags |= OPTION_MASK_ISA_ABM;
@@ -2829,6 +2979,9 @@ override_options (bool main_args_p)
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_MOVBE
+ && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_MOVBE))
+ ix86_isa_flags |= OPTION_MASK_ISA_MOVBE;
if (processor_alias_table[i].flags & PTA_AES
&& !(ix86_isa_flags_explicit & OPTION_MASK_ISA_AES))
ix86_isa_flags |= OPTION_MASK_ISA_AES;
@@ -3092,12 +3245,10 @@ override_options (bool main_args_p)
if (ix86_force_align_arg_pointer == -1)
ix86_force_align_arg_pointer = STACK_REALIGN_DEFAULT;
+ ix86_default_incoming_stack_boundary = PREFERRED_STACK_BOUNDARY;
+
/* Validate -mincoming-stack-boundary= value or default it to
MIN_STACK_BOUNDARY/PREFERRED_STACK_BOUNDARY. */
- if (ix86_force_align_arg_pointer)
- ix86_default_incoming_stack_boundary = MIN_STACK_BOUNDARY;
- else
- ix86_default_incoming_stack_boundary = PREFERRED_STACK_BOUNDARY;
ix86_incoming_stack_boundary = ix86_default_incoming_stack_boundary;
if (ix86_incoming_stack_boundary_string)
{
@@ -3503,6 +3654,7 @@ ix86_valid_target_attribute_inner_p (tree args, char *p_strings[])
IX86_ATTR_ISA ("sse4a", OPT_msse4a),
IX86_ATTR_ISA ("sse5", OPT_msse5),
IX86_ATTR_ISA ("ssse3", OPT_mssse3),
+ IX86_ATTR_ISA ("lwp", OPT_mlwp),
/* string options */
IX86_ATTR_STR ("arch=", IX86_FUNCTION_SPECIFIC_ARCH),
@@ -4147,7 +4299,8 @@ ix86_function_ok_for_sibcall (tree decl, tree exp)
/* If we need to align the outgoing stack, then sibcalling would
unalign the stack, which may break the called function. */
- if (ix86_incoming_stack_boundary < PREFERRED_STACK_BOUNDARY)
+ if (ix86_minimum_incoming_stack_boundary (true)
+ < PREFERRED_STACK_BOUNDARY)
return false;
if (decl)
@@ -4608,14 +4761,14 @@ ix86_function_arg_regno_p (int regno)
default ABI. */
/* RAX is used as hidden argument to va_arg functions. */
- if (DEFAULT_ABI == SYSV_ABI && regno == AX_REG)
+ if (ix86_abi == SYSV_ABI && regno == AX_REG)
return true;
- if (DEFAULT_ABI == MS_ABI)
+ if (ix86_abi == MS_ABI)
parm_regs = x86_64_ms_abi_int_parameter_registers;
else
parm_regs = x86_64_int_parameter_registers;
- for (i = 0; i < (DEFAULT_ABI == MS_ABI ? X64_REGPARM_MAX
+ for (i = 0; i < (ix86_abi == MS_ABI ? X64_REGPARM_MAX
: X86_64_REGPARM_MAX); i++)
if (regno == parm_regs[i])
return true;
@@ -4643,7 +4796,7 @@ ix86_must_pass_in_stack (enum machine_mode mode, const_tree type)
int
ix86_reg_parm_stack_space (const_tree fndecl)
{
- int call_abi = SYSV_ABI;
+ enum calling_abi call_abi = SYSV_ABI;
if (fndecl != NULL_TREE && TREE_CODE (fndecl) == FUNCTION_DECL)
call_abi = ix86_function_abi (fndecl);
else
@@ -4655,37 +4808,39 @@ ix86_reg_parm_stack_space (const_tree fndecl)
/* Returns value SYSV_ABI, MS_ABI dependent on fntype, specifying the
call abi used. */
-int
+enum calling_abi
ix86_function_type_abi (const_tree fntype)
{
if (TARGET_64BIT && fntype != NULL)
{
- int abi;
- if (DEFAULT_ABI == SYSV_ABI)
- abi = lookup_attribute ("ms_abi", TYPE_ATTRIBUTES (fntype)) ? MS_ABI : SYSV_ABI;
- else
- abi = lookup_attribute ("sysv_abi", TYPE_ATTRIBUTES (fntype)) ? SYSV_ABI : MS_ABI;
-
+ enum calling_abi abi = ix86_abi;
+ if (abi == SYSV_ABI)
+ {
+ if (lookup_attribute ("ms_abi", TYPE_ATTRIBUTES (fntype)))
+ abi = MS_ABI;
+ }
+ else if (lookup_attribute ("sysv_abi", TYPE_ATTRIBUTES (fntype)))
+ abi = SYSV_ABI;
return abi;
}
- return DEFAULT_ABI;
+ return ix86_abi;
}
-int
+static enum calling_abi
ix86_function_abi (const_tree fndecl)
{
if (! fndecl)
- return DEFAULT_ABI;
+ return ix86_abi;
return ix86_function_type_abi (TREE_TYPE (fndecl));
}
/* Returns value SYSV_ABI, MS_ABI dependent on cfun, specifying the
call abi used. */
-int
+enum calling_abi
ix86_cfun_abi (void)
{
if (! cfun || ! TARGET_64BIT)
- return DEFAULT_ABI;
+ return ix86_abi;
return cfun->machine->call_abi;
}
@@ -4699,7 +4854,7 @@ void
ix86_call_abi_override (const_tree fndecl)
{
if (fndecl == NULL_TREE)
- cfun->machine->call_abi = DEFAULT_ABI;
+ cfun->machine->call_abi = ix86_abi;
else
cfun->machine->call_abi = ix86_function_type_abi (TREE_TYPE (fndecl));
}
@@ -4740,8 +4895,8 @@ init_cumulative_args (CUMULATIVE_ARGS *cum, /* Argument info to initialize */
cum->nregs = ix86_regparm;
if (TARGET_64BIT)
{
- if (cum->call_abi != DEFAULT_ABI)
- cum->nregs = DEFAULT_ABI != SYSV_ABI ? X86_64_REGPARM_MAX
+ if (cum->call_abi != ix86_abi)
+ cum->nregs = ix86_abi != SYSV_ABI ? X86_64_REGPARM_MAX
: X64_REGPARM_MAX;
}
if (TARGET_SSE)
@@ -4749,8 +4904,8 @@ init_cumulative_args (CUMULATIVE_ARGS *cum, /* Argument info to initialize */
cum->sse_nregs = SSE_REGPARM_MAX;
if (TARGET_64BIT)
{
- if (cum->call_abi != DEFAULT_ABI)
- cum->sse_nregs = DEFAULT_ABI != SYSV_ABI ? X86_64_SSE_REGPARM_MAX
+ if (cum->call_abi != ix86_abi)
+ cum->sse_nregs = ix86_abi != SYSV_ABI ? X86_64_SSE_REGPARM_MAX
: X64_SSE_REGPARM_MAX;
}
}
@@ -5716,7 +5871,7 @@ function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
if (type)
mode = type_natural_mode (type, NULL);
- if (TARGET_64BIT && (cum ? cum->call_abi : DEFAULT_ABI) == MS_ABI)
+ if (TARGET_64BIT && (cum ? cum->call_abi : ix86_abi) == MS_ABI)
function_arg_advance_ms_64 (cum, bytes, words);
else if (TARGET_64BIT)
function_arg_advance_64 (cum, mode, type, words, named);
@@ -5862,9 +6017,9 @@ function_arg_64 (CUMULATIVE_ARGS *cum, enum machine_mode mode,
if (mode == VOIDmode)
return GEN_INT (cum->maybe_vaarg
? (cum->sse_nregs < 0
- ? (cum->call_abi == DEFAULT_ABI
+ ? (cum->call_abi == ix86_abi
? SSE_REGPARM_MAX
- : (DEFAULT_ABI != SYSV_ABI ? X86_64_SSE_REGPARM_MAX
+ : (ix86_abi != SYSV_ABI ? X86_64_SSE_REGPARM_MAX
: X64_SSE_REGPARM_MAX))
: cum->sse_regno)
: -1);
@@ -5958,7 +6113,7 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode omode,
if (type && TREE_CODE (type) == VECTOR_TYPE)
mode = type_natural_mode (type, cum);
- if (TARGET_64BIT && (cum ? cum->call_abi : DEFAULT_ABI) == MS_ABI)
+ if (TARGET_64BIT && (cum ? cum->call_abi : ix86_abi) == MS_ABI)
return function_arg_ms_64 (cum, mode, omode, named, bytes);
else if (TARGET_64BIT)
return function_arg_64 (cum, mode, omode, type, named);
@@ -5978,7 +6133,7 @@ ix86_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
const_tree type, bool named ATTRIBUTE_UNUSED)
{
/* See Windows x64 Software Convention. */
- if (TARGET_64BIT && (cum ? cum->call_abi : DEFAULT_ABI) == MS_ABI)
+ if (TARGET_64BIT && (cum ? cum->call_abi : ix86_abi) == MS_ABI)
{
int msize = (int) GET_MODE_SIZE (mode);
if (type)
@@ -6118,7 +6273,7 @@ ix86_function_value_regno_p (int regno)
/* TODO: The function should depend on current function ABI but
builtins.c would need updating then. Therefore we use the
default ABI. */
- if (TARGET_64BIT && DEFAULT_ABI == MS_ABI)
+ if (TARGET_64BIT && ix86_abi == MS_ABI)
return false;
return TARGET_FLOAT_RETURNS_IN_80387;
@@ -6514,13 +6669,13 @@ ix86_build_builtin_va_list_abi (enum calling_abi abi)
static tree
ix86_build_builtin_va_list (void)
{
- tree ret = ix86_build_builtin_va_list_abi (DEFAULT_ABI);
+ tree ret = ix86_build_builtin_va_list_abi (ix86_abi);
/* Initialize abi specific va_list builtin types. */
if (TARGET_64BIT)
{
tree t;
- if (DEFAULT_ABI == MS_ABI)
+ if (ix86_abi == MS_ABI)
{
t = ix86_build_builtin_va_list_abi (SYSV_ABI);
if (TREE_CODE (t) != RECORD_TYPE)
@@ -6534,7 +6689,7 @@ ix86_build_builtin_va_list (void)
t = build_variant_type_copy (t);
sysv_va_list_type_node = t;
}
- if (DEFAULT_ABI != MS_ABI)
+ if (ix86_abi != MS_ABI)
{
t = ix86_build_builtin_va_list_abi (MS_ABI);
if (TREE_CODE (t) != RECORD_TYPE)
@@ -6567,8 +6722,8 @@ setup_incoming_varargs_64 (CUMULATIVE_ARGS *cum)
int i;
int regparm = ix86_regparm;
- if (cum->call_abi != DEFAULT_ABI)
- regparm = DEFAULT_ABI != SYSV_ABI ? X86_64_REGPARM_MAX : X64_REGPARM_MAX;
+ if (cum->call_abi != ix86_abi)
+ regparm = ix86_abi != SYSV_ABI ? X86_64_REGPARM_MAX : X64_REGPARM_MAX;
/* GPR size of varargs save area. */
if (cfun->va_list_gpr_size)
@@ -6721,7 +6876,7 @@ is_va_list_char_pointer (tree type)
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));
+ || (ix86_abi == MS_ABI && canonic == va_list_type_node));
}
/* Implement va_start. */
@@ -6965,7 +7120,7 @@ ix86_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
}
if (need_temp)
{
- int i;
+ int i, prev_size = 0;
tree temp = create_tmp_var (type, "va_arg_tmp");
/* addr = &temp; */
@@ -6977,13 +7132,29 @@ ix86_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
rtx slot = XVECEXP (container, 0, i);
rtx reg = XEXP (slot, 0);
enum machine_mode mode = GET_MODE (reg);
- tree piece_type = lang_hooks.types.type_for_mode (mode, 1);
- tree addr_type = build_pointer_type (piece_type);
- tree daddr_type = build_pointer_type_for_mode (piece_type,
- ptr_mode, true);
+ tree piece_type;
+ tree addr_type;
+ tree daddr_type;
tree src_addr, src;
int src_offset;
tree dest_addr, dest;
+ int cur_size = GET_MODE_SIZE (mode);
+
+ if (prev_size + cur_size > size)
+ {
+ cur_size = size - prev_size;
+ mode = mode_for_size (cur_size * BITS_PER_UNIT, MODE_INT, 1);
+ if (mode == BLKmode)
+ mode = QImode;
+ }
+ piece_type = lang_hooks.types.type_for_mode (mode, 1);
+ if (mode == GET_MODE (reg))
+ addr_type = build_pointer_type (piece_type);
+ else
+ addr_type = build_pointer_type_for_mode (piece_type, ptr_mode,
+ true);
+ daddr_type = build_pointer_type_for_mode (piece_type, ptr_mode,
+ true);
if (SSE_REGNO_P (REGNO (reg)))
{
@@ -6998,14 +7169,26 @@ ix86_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
src_addr = fold_convert (addr_type, src_addr);
src_addr = fold_build2 (POINTER_PLUS_EXPR, addr_type, src_addr,
size_int (src_offset));
- src = build_va_arg_indirect_ref (src_addr);
dest_addr = fold_convert (daddr_type, addr);
dest_addr = fold_build2 (POINTER_PLUS_EXPR, daddr_type, dest_addr,
size_int (INTVAL (XEXP (slot, 1))));
- dest = build_va_arg_indirect_ref (dest_addr);
+ if (cur_size == GET_MODE_SIZE (mode))
+ {
+ src = build_va_arg_indirect_ref (src_addr);
+ dest = build_va_arg_indirect_ref (dest_addr);
- gimplify_assign (dest, src, pre_p);
+ gimplify_assign (dest, src, pre_p);
+ }
+ else
+ {
+ tree copy
+ = build_call_expr (implicit_built_in_decls[BUILT_IN_MEMCPY],
+ 3, dest_addr, src_addr,
+ size_int (cur_size));
+ gimplify_and_add (copy, pre_p);
+ }
+ prev_size += cur_size;
}
}
@@ -8088,37 +8271,58 @@ find_drap_reg (void)
}
}
-/* Update incoming stack boundary and estimated stack alignment. */
+/* Return minimum incoming stack alignment. */
-static void
-ix86_update_stack_boundary (void)
+static unsigned int
+ix86_minimum_incoming_stack_boundary (bool sibcall)
{
+ unsigned int incoming_stack_boundary;
+
/* Prefer the one specified at command line. */
- ix86_incoming_stack_boundary
- = (ix86_user_incoming_stack_boundary
- ? ix86_user_incoming_stack_boundary
- : ix86_default_incoming_stack_boundary);
+ if (ix86_user_incoming_stack_boundary)
+ incoming_stack_boundary = ix86_user_incoming_stack_boundary;
+ /* In 32bit, use MIN_STACK_BOUNDARY for incoming stack boundary
+ if -mstackrealign is used, it isn't used for sibcall check and
+ estimated stack alignment is 128bit. */
+ else if (!sibcall
+ && !TARGET_64BIT
+ && ix86_force_align_arg_pointer
+ && crtl->stack_alignment_estimated == 128)
+ incoming_stack_boundary = MIN_STACK_BOUNDARY;
+ else
+ incoming_stack_boundary = ix86_default_incoming_stack_boundary;
/* Incoming stack alignment can be changed on individual functions
via force_align_arg_pointer attribute. We use the smallest
incoming stack boundary. */
- if (ix86_incoming_stack_boundary > MIN_STACK_BOUNDARY
+ if (incoming_stack_boundary > MIN_STACK_BOUNDARY
&& lookup_attribute (ix86_force_align_arg_pointer_string,
TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl))))
- ix86_incoming_stack_boundary = MIN_STACK_BOUNDARY;
+ incoming_stack_boundary = MIN_STACK_BOUNDARY;
/* The incoming stack frame has to be aligned at least at
parm_stack_boundary. */
- if (ix86_incoming_stack_boundary < crtl->parm_stack_boundary)
- ix86_incoming_stack_boundary = crtl->parm_stack_boundary;
+ if (incoming_stack_boundary < crtl->parm_stack_boundary)
+ incoming_stack_boundary = crtl->parm_stack_boundary;
/* Stack at entrance of main is aligned by runtime. We use the
smallest incoming stack boundary. */
- if (ix86_incoming_stack_boundary > MAIN_STACK_BOUNDARY
+ if (incoming_stack_boundary > MAIN_STACK_BOUNDARY
&& DECL_NAME (current_function_decl)
&& MAIN_NAME_P (DECL_NAME (current_function_decl))
&& DECL_FILE_SCOPE_P (current_function_decl))
- ix86_incoming_stack_boundary = MAIN_STACK_BOUNDARY;
+ incoming_stack_boundary = MAIN_STACK_BOUNDARY;
+
+ return incoming_stack_boundary;
+}
+
+/* Update incoming stack boundary and estimated stack alignment. */
+
+static void
+ix86_update_stack_boundary (void)
+{
+ ix86_incoming_stack_boundary
+ = ix86_minimum_incoming_stack_boundary (false);
/* x86_64 vararg needs 16byte stack alignment for register save
area. */
@@ -13228,6 +13432,316 @@ ix86_expand_unary_operator (enum rtx_code code, enum machine_mode mode,
emit_move_insn (operands[0], dst);
}
+#define LEA_SEARCH_THRESHOLD 12
+
+/* Search backward for non-agu definition of register number REGNO1
+ or register number REGNO2 in INSN's basic block until
+ 1. Pass LEA_SEARCH_THRESHOLD instructions, or
+ 2. Reach BB boundary, or
+ 3. Reach agu definition.
+ Returns the distance between the non-agu definition point and INSN.
+ If no definition point, returns -1. */
+
+static int
+distance_non_agu_define (unsigned int regno1, unsigned int regno2,
+ rtx insn)
+{
+ basic_block bb = BLOCK_FOR_INSN (insn);
+ int distance = 0;
+ df_ref *def_rec;
+ enum attr_type insn_type;
+
+ if (insn != BB_HEAD (bb))
+ {
+ rtx prev = PREV_INSN (insn);
+ while (prev && distance < LEA_SEARCH_THRESHOLD)
+ {
+ if (INSN_P (prev))
+ {
+ distance++;
+ for (def_rec = DF_INSN_DEFS (prev); *def_rec; def_rec++)
+ if (DF_REF_TYPE (*def_rec) == DF_REF_REG_DEF
+ && !DF_REF_IS_ARTIFICIAL (*def_rec)
+ && (regno1 == DF_REF_REGNO (*def_rec)
+ || regno2 == DF_REF_REGNO (*def_rec)))
+ {
+ insn_type = get_attr_type (prev);
+ if (insn_type != TYPE_LEA)
+ goto done;
+ }
+ }
+ if (prev == BB_HEAD (bb))
+ break;
+ prev = PREV_INSN (prev);
+ }
+ }
+
+ if (distance < LEA_SEARCH_THRESHOLD)
+ {
+ edge e;
+ edge_iterator ei;
+ bool simple_loop = false;
+
+ FOR_EACH_EDGE (e, ei, bb->preds)
+ if (e->src == bb)
+ {
+ simple_loop = true;
+ break;
+ }
+
+ if (simple_loop)
+ {
+ rtx prev = BB_END (bb);
+ while (prev
+ && prev != insn
+ && distance < LEA_SEARCH_THRESHOLD)
+ {
+ if (INSN_P (prev))
+ {
+ distance++;
+ for (def_rec = DF_INSN_DEFS (prev); *def_rec; def_rec++)
+ if (DF_REF_TYPE (*def_rec) == DF_REF_REG_DEF
+ && !DF_REF_IS_ARTIFICIAL (*def_rec)
+ && (regno1 == DF_REF_REGNO (*def_rec)
+ || regno2 == DF_REF_REGNO (*def_rec)))
+ {
+ insn_type = get_attr_type (prev);
+ if (insn_type != TYPE_LEA)
+ goto done;
+ }
+ }
+ prev = PREV_INSN (prev);
+ }
+ }
+ }
+
+ distance = -1;
+
+done:
+ /* get_attr_type may modify recog data. We want to make sure
+ that recog data is valid for instruction INSN, on which
+ distance_non_agu_define is called. INSN is unchanged here. */
+ extract_insn_cached (insn);
+ return distance;
+}
+
+/* Return the distance between INSN and the next insn that uses
+ register number REGNO0 in memory address. Return -1 if no such
+ a use is found within LEA_SEARCH_THRESHOLD or REGNO0 is set. */
+
+static int
+distance_agu_use (unsigned int regno0, rtx insn)
+{
+ basic_block bb = BLOCK_FOR_INSN (insn);
+ int distance = 0;
+ df_ref *def_rec;
+ df_ref *use_rec;
+
+ if (insn != BB_END (bb))
+ {
+ rtx next = NEXT_INSN (insn);
+ while (next && distance < LEA_SEARCH_THRESHOLD)
+ {
+ if (INSN_P (next))
+ {
+ distance++;
+
+ for (use_rec = DF_INSN_USES (next); *use_rec; use_rec++)
+ if ((DF_REF_TYPE (*use_rec) == DF_REF_REG_MEM_LOAD
+ || DF_REF_TYPE (*use_rec) == DF_REF_REG_MEM_STORE)
+ && regno0 == DF_REF_REGNO (*use_rec))
+ {
+ /* Return DISTANCE if OP0 is used in memory
+ address in NEXT. */
+ return distance;
+ }
+
+ for (def_rec = DF_INSN_DEFS (next); *def_rec; def_rec++)
+ if (DF_REF_TYPE (*def_rec) == DF_REF_REG_DEF
+ && !DF_REF_IS_ARTIFICIAL (*def_rec)
+ && regno0 == DF_REF_REGNO (*def_rec))
+ {
+ /* Return -1 if OP0 is set in NEXT. */
+ return -1;
+ }
+ }
+ if (next == BB_END (bb))
+ break;
+ next = NEXT_INSN (next);
+ }
+ }
+
+ if (distance < LEA_SEARCH_THRESHOLD)
+ {
+ edge e;
+ edge_iterator ei;
+ bool simple_loop = false;
+
+ FOR_EACH_EDGE (e, ei, bb->succs)
+ if (e->dest == bb)
+ {
+ simple_loop = true;
+ break;
+ }
+
+ if (simple_loop)
+ {
+ rtx next = BB_HEAD (bb);
+ while (next
+ && next != insn
+ && distance < LEA_SEARCH_THRESHOLD)
+ {
+ if (INSN_P (next))
+ {
+ distance++;
+
+ for (use_rec = DF_INSN_USES (next); *use_rec; use_rec++)
+ if ((DF_REF_TYPE (*use_rec) == DF_REF_REG_MEM_LOAD
+ || DF_REF_TYPE (*use_rec) == DF_REF_REG_MEM_STORE)
+ && regno0 == DF_REF_REGNO (*use_rec))
+ {
+ /* Return DISTANCE if OP0 is used in memory
+ address in NEXT. */
+ return distance;
+ }
+
+ for (def_rec = DF_INSN_DEFS (next); *def_rec; def_rec++)
+ if (DF_REF_TYPE (*def_rec) == DF_REF_REG_DEF
+ && !DF_REF_IS_ARTIFICIAL (*def_rec)
+ && regno0 == DF_REF_REGNO (*def_rec))
+ {
+ /* Return -1 if OP0 is set in NEXT. */
+ return -1;
+ }
+
+ }
+ next = NEXT_INSN (next);
+ }
+ }
+ }
+
+ return -1;
+}
+
+/* Define this macro to tune LEA priority vs ADD, it take effect when
+ there is a dilemma of choicing LEA or ADD
+ Negative value: ADD is more preferred than LEA
+ Zero: Netrual
+ Positive value: LEA is more preferred than ADD*/
+#define IX86_LEA_PRIORITY 2
+
+/* Return true if it is ok to optimize an ADD operation to LEA
+ operation to avoid flag register consumation. For the processors
+ like ATOM, if the destination register of LEA holds an actual
+ address which will be used soon, LEA is better and otherwise ADD
+ is better. */
+
+bool
+ix86_lea_for_add_ok (enum rtx_code code ATTRIBUTE_UNUSED,
+ rtx insn, rtx operands[])
+{
+ unsigned int regno0 = true_regnum (operands[0]);
+ unsigned int regno1 = true_regnum (operands[1]);
+ unsigned int regno2;
+
+ if (!TARGET_OPT_AGU || optimize_function_for_size_p (cfun))
+ return regno0 != regno1;
+
+ regno2 = true_regnum (operands[2]);
+
+ /* If a = b + c, (a!=b && a!=c), must use lea form. */
+ if (regno0 != regno1 && regno0 != regno2)
+ return true;
+ else
+ {
+ int dist_define, dist_use;
+ dist_define = distance_non_agu_define (regno1, regno2, insn);
+ if (dist_define <= 0)
+ return true;
+
+ /* If this insn has both backward non-agu dependence and forward
+ agu dependence, the one with short distance take effect. */
+ dist_use = distance_agu_use (regno0, insn);
+ if (dist_use <= 0
+ || (dist_define + IX86_LEA_PRIORITY) < dist_use)
+ return false;
+
+ return true;
+ }
+}
+
+/* Return true if destination reg of SET_BODY is shift count of
+ USE_BODY. */
+
+static bool
+ix86_dep_by_shift_count_body (const_rtx set_body, const_rtx use_body)
+{
+ rtx set_dest;
+ rtx shift_rtx;
+ int i;
+
+ /* Retrieve destination of SET_BODY. */
+ switch (GET_CODE (set_body))
+ {
+ case SET:
+ set_dest = SET_DEST (set_body);
+ if (!set_dest || !REG_P (set_dest))
+ return false;
+ break;
+ case PARALLEL:
+ for (i = XVECLEN (set_body, 0) - 1; i >= 0; i--)
+ if (ix86_dep_by_shift_count_body (XVECEXP (set_body, 0, i),
+ use_body))
+ return true;
+ default:
+ return false;
+ break;
+ }
+
+ /* Retrieve shift count of USE_BODY. */
+ switch (GET_CODE (use_body))
+ {
+ case SET:
+ shift_rtx = XEXP (use_body, 1);
+ break;
+ case PARALLEL:
+ for (i = XVECLEN (use_body, 0) - 1; i >= 0; i--)
+ if (ix86_dep_by_shift_count_body (set_body,
+ XVECEXP (use_body, 0, i)))
+ return true;
+ default:
+ return false;
+ break;
+ }
+
+ if (shift_rtx
+ && (GET_CODE (shift_rtx) == ASHIFT
+ || GET_CODE (shift_rtx) == LSHIFTRT
+ || GET_CODE (shift_rtx) == ASHIFTRT
+ || GET_CODE (shift_rtx) == ROTATE
+ || GET_CODE (shift_rtx) == ROTATERT))
+ {
+ rtx shift_count = XEXP (shift_rtx, 1);
+
+ /* Return true if shift count is dest of SET_BODY. */
+ if (REG_P (shift_count)
+ && true_regnum (set_dest) == true_regnum (shift_count))
+ return true;
+ }
+
+ return false;
+}
+
+/* Return true if destination reg of SET_INSN is shift count of
+ USE_INSN. */
+
+bool
+ix86_dep_by_shift_count (const_rtx set_insn, const_rtx use_insn)
+{
+ return ix86_dep_by_shift_count_body (PATTERN (set_insn),
+ PATTERN (use_insn));
+}
+
/* Return TRUE or FALSE depending on whether the unary operator meets the
appropriate constraints. */
@@ -19084,7 +19598,7 @@ ix86_init_machine_status (void)
f = GGC_CNEW (struct machine_function);
f->use_fast_prologue_epilogue_nregs = -1;
f->tls_descriptor_call_expanded_p = 0;
- f->call_abi = DEFAULT_ABI;
+ f->call_abi = ix86_abi;
return f;
}
@@ -19345,6 +19859,7 @@ ix86_issue_rate (void)
switch (ix86_tune)
{
case PROCESSOR_PENTIUM:
+ case PROCESSOR_ATOM:
case PROCESSOR_K6:
return 2;
@@ -19411,41 +19926,21 @@ ix86_flags_dependent (rtx insn, rtx dep_insn, enum attr_type insn_type)
return 1;
}
-/* A subroutine of ix86_adjust_cost -- return true iff INSN has a memory
- address with operands set by DEP_INSN. */
+/* Return true iff USE_INSN has a memory address with operands set by
+ SET_INSN. */
-static int
-ix86_agi_dependent (rtx insn, rtx dep_insn, enum attr_type insn_type)
+bool
+ix86_agi_dependent (rtx set_insn, rtx use_insn)
{
- rtx addr;
-
- if (insn_type == TYPE_LEA
- && TARGET_PENTIUM)
- {
- addr = PATTERN (insn);
-
- if (GET_CODE (addr) == PARALLEL)
- addr = XVECEXP (addr, 0, 0);
-
- gcc_assert (GET_CODE (addr) == SET);
-
- addr = SET_SRC (addr);
- }
- else
- {
- int i;
- extract_insn_cached (insn);
- for (i = recog_data.n_operands - 1; i >= 0; --i)
- if (MEM_P (recog_data.operand[i]))
- {
- addr = XEXP (recog_data.operand[i], 0);
- goto found;
- }
- return 0;
- found:;
- }
-
- return modified_in_p (addr, dep_insn);
+ int i;
+ extract_insn_cached (use_insn);
+ for (i = recog_data.n_operands - 1; i >= 0; --i)
+ if (MEM_P (recog_data.operand[i]))
+ {
+ rtx addr = XEXP (recog_data.operand[i], 0);
+ return modified_in_p (addr, set_insn) != 0;
+ }
+ return false;
}
static int
@@ -19473,7 +19968,20 @@ ix86_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
{
case PROCESSOR_PENTIUM:
/* Address Generation Interlock adds a cycle of latency. */
- if (ix86_agi_dependent (insn, dep_insn, insn_type))
+ if (insn_type == TYPE_LEA)
+ {
+ rtx addr = PATTERN (insn);
+
+ if (GET_CODE (addr) == PARALLEL)
+ addr = XVECEXP (addr, 0, 0);
+
+ gcc_assert (GET_CODE (addr) == SET);
+
+ addr = SET_SRC (addr);
+ if (modified_in_p (addr, dep_insn))
+ cost += 1;
+ }
+ else if (ix86_agi_dependent (dep_insn, insn))
cost += 1;
/* ??? Compares pair with jump/setcc. */
@@ -19483,7 +19991,7 @@ ix86_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
/* Floating point stores require value to be ready one cycle earlier. */
if (insn_type == TYPE_FMOV
&& get_attr_memory (insn) == MEMORY_STORE
- && !ix86_agi_dependent (insn, dep_insn, insn_type))
+ && !ix86_agi_dependent (dep_insn, insn))
cost += 1;
break;
@@ -19506,7 +20014,7 @@ ix86_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
in parallel with previous instruction in case
previous instruction is not needed to compute the address. */
if ((memory == MEMORY_LOAD || memory == MEMORY_BOTH)
- && !ix86_agi_dependent (insn, dep_insn, insn_type))
+ && !ix86_agi_dependent (dep_insn, insn))
{
/* Claim moves to take one cycle, as core can issue one load
at time and the next load can start cycle later. */
@@ -19535,7 +20043,7 @@ ix86_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
in parallel with previous instruction in case
previous instruction is not needed to compute the address. */
if ((memory == MEMORY_LOAD || memory == MEMORY_BOTH)
- && !ix86_agi_dependent (insn, dep_insn, insn_type))
+ && !ix86_agi_dependent (dep_insn, insn))
{
/* Claim moves to take one cycle, as core can issue one load
at time and the next load can start cycle later. */
@@ -19552,6 +20060,7 @@ ix86_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
case PROCESSOR_ATHLON:
case PROCESSOR_K8:
case PROCESSOR_AMDFAM10:
+ case PROCESSOR_ATOM:
case PROCESSOR_GENERIC32:
case PROCESSOR_GENERIC64:
memory = get_attr_memory (insn);
@@ -19560,7 +20069,7 @@ ix86_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
in parallel with previous instruction in case
previous instruction is not needed to compute the address. */
if ((memory == MEMORY_LOAD || memory == MEMORY_BOTH)
- && !ix86_agi_dependent (insn, dep_insn, insn_type))
+ && !ix86_agi_dependent (dep_insn, insn))
{
enum attr_unit unit = get_attr_unit (insn);
int loadcost = 3;
@@ -20815,6 +21324,14 @@ enum ix86_builtins
IX86_BUILTIN_PCOMFALSEQ,
IX86_BUILTIN_PCOMTRUEQ,
+ /* LWP instructions. */
+ IX86_BUILTIN_LLWPCB,
+ IX86_BUILTIN_SLWPCB,
+ IX86_BUILTIN_LWPVAL32,
+ IX86_BUILTIN_LWPVAL64,
+ IX86_BUILTIN_LWPINS32,
+ IX86_BUILTIN_LWPINS64,
+
IX86_BUILTIN_MAX
};
@@ -20998,6 +21515,8 @@ enum ix86_special_builtin_type
{
SPECIAL_FTYPE_UNKNOWN,
VOID_FTYPE_VOID,
+ VOID_FTYPE_PVOID,
+ PVOID_FTYPE_VOID,
V32QI_FTYPE_PCCHAR,
V16QI_FTYPE_PCCHAR,
V8SF_FTYPE_PCV4SF,
@@ -21027,7 +21546,13 @@ enum ix86_special_builtin_type
VOID_FTYPE_PV8SF_V8SF_V8SF,
VOID_FTYPE_PV4DF_V4DF_V4DF,
VOID_FTYPE_PV4SF_V4SF_V4SF,
- VOID_FTYPE_PV2DF_V2DF_V2DF
+ VOID_FTYPE_PV2DF_V2DF_V2DF,
+ VOID_FTYPE_USHORT_UINT_USHORT,
+ VOID_FTYPE_UINT_UINT_UINT,
+ VOID_FTYPE_UINT64_UINT_UINT,
+ UCHAR_FTYPE_USHORT_UINT_USHORT,
+ UCHAR_FTYPE_UINT_UINT_UINT,
+ UCHAR_FTYPE_UINT64_UINT_UINT
};
/* Builtin types */
@@ -21266,6 +21791,14 @@ static const struct builtin_description bdesc_special_args[] =
{ OPTION_MASK_ISA_AVX, CODE_FOR_avx_maskstoreps, "__builtin_ia32_maskstoreps", IX86_BUILTIN_MASKSTOREPS, UNKNOWN, (int) VOID_FTYPE_PV4SF_V4SF_V4SF },
{ OPTION_MASK_ISA_AVX, CODE_FOR_avx_maskstorepd256, "__builtin_ia32_maskstorepd256", IX86_BUILTIN_MASKSTOREPD256, UNKNOWN, (int) VOID_FTYPE_PV4DF_V4DF_V4DF },
{ OPTION_MASK_ISA_AVX, CODE_FOR_avx_maskstoreps256, "__builtin_ia32_maskstoreps256", IX86_BUILTIN_MASKSTOREPS256, UNKNOWN, (int) VOID_FTYPE_PV8SF_V8SF_V8SF },
+
+ { OPTION_MASK_ISA_LWP, CODE_FOR_lwp_llwpcb, "__builtin_ia32_llwpcb", IX86_BUILTIN_LLWPCB, UNKNOWN, (int) VOID_FTYPE_PVOID },
+ { OPTION_MASK_ISA_LWP, CODE_FOR_lwp_slwpcb, "__builtin_ia32_slwpcb", IX86_BUILTIN_SLWPCB, UNKNOWN, (int) PVOID_FTYPE_VOID },
+ { OPTION_MASK_ISA_LWP, CODE_FOR_lwp_lwpvalsi3, "__builtin_ia32_lwpval32", IX86_BUILTIN_LWPVAL32, UNKNOWN, (int) VOID_FTYPE_UINT_UINT_UINT },
+ { OPTION_MASK_ISA_LWP, CODE_FOR_lwp_lwpvaldi3, "__builtin_ia32_lwpval64", IX86_BUILTIN_LWPVAL64, UNKNOWN, (int) VOID_FTYPE_UINT64_UINT_UINT },
+ { OPTION_MASK_ISA_LWP, CODE_FOR_lwp_lwpinssi3, "__builtin_ia32_lwpins32", IX86_BUILTIN_LWPINS32, UNKNOWN, (int) UCHAR_FTYPE_UINT_UINT_UINT },
+ { OPTION_MASK_ISA_LWP, CODE_FOR_lwp_lwpinsdi3, "__builtin_ia32_lwpins64", IX86_BUILTIN_LWPINS64, UNKNOWN, (int) UCHAR_FTYPE_UINT64_UINT_UINT },
+
};
/* Builtins with variable number of arguments. */
@@ -22255,6 +22788,7 @@ ix86_init_mmx_sse_builtins (void)
NULL_TREE);
tree unsigned_ftype_void
= build_function_type (unsigned_type_node, void_list_node);
+
tree v2si_ftype_v4sf
= build_function_type_list (V2SI_type_node, V4SF_type_node, NULL_TREE);
/* Loads/stores. */
@@ -22915,6 +23449,56 @@ ix86_init_mmx_sse_builtins (void)
= build_function_type_list (V2DF_type_node,
V2DF_type_node, V2DI_type_node, NULL_TREE);
+ /* LWP instructions. */
+
+ tree pvoid_ftype_void
+ = build_function_type (ptr_type_node, void_list_node);
+
+ tree void_ftype_pvoid
+ = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
+
+ tree void_ftype_ushort_unsigned_ushort
+ = build_function_type_list (void_type_node,
+ short_unsigned_type_node,
+ unsigned_type_node,
+ short_unsigned_type_node,
+ NULL_TREE);
+
+ tree void_ftype_unsigned_unsigned_unsigned
+ = build_function_type_list (void_type_node,
+ unsigned_type_node,
+ unsigned_type_node,
+ unsigned_type_node,
+ NULL_TREE);
+
+ tree void_ftype_uint64_unsigned_unsigned
+ = build_function_type_list (void_type_node,
+ long_long_unsigned_type_node,
+ unsigned_type_node,
+ unsigned_type_node,
+ NULL_TREE);
+
+ tree uchar_ftype_ushort_unsigned_ushort
+ = build_function_type_list (unsigned_char_type_node,
+ short_unsigned_type_node,
+ unsigned_type_node,
+ short_unsigned_type_node,
+ NULL_TREE);
+
+ tree uchar_ftype_unsigned_unsigned_unsigned
+ = build_function_type_list (unsigned_char_type_node,
+ unsigned_type_node,
+ unsigned_type_node,
+ unsigned_type_node,
+ NULL_TREE);
+
+ tree uchar_ftype_uint64_unsigned_unsigned
+ = build_function_type_list (unsigned_char_type_node,
+ long_long_unsigned_type_node,
+ unsigned_type_node,
+ unsigned_type_node,
+ NULL_TREE);
+
tree ftype;
/* Add all special builtins with variable number of operands. */
@@ -23022,6 +23606,31 @@ ix86_init_mmx_sse_builtins (void)
case VOID_FTYPE_PV2DF_V2DF_V2DF:
type = void_ftype_pv2df_v2df_v2df;
break;
+ case VOID_FTYPE_USHORT_UINT_USHORT:
+ type = void_ftype_ushort_unsigned_ushort;
+ break;
+ case VOID_FTYPE_UINT_UINT_UINT:
+ type = void_ftype_unsigned_unsigned_unsigned;
+ break;
+ case VOID_FTYPE_UINT64_UINT_UINT:
+ type = void_ftype_uint64_unsigned_unsigned;
+ break;
+ case VOID_FTYPE_PVOID:
+ type = void_ftype_pvoid;
+ break;
+ case PVOID_FTYPE_VOID:
+ type = pvoid_ftype_void;
+ break;
+ case UCHAR_FTYPE_USHORT_UINT_USHORT:
+ type = uchar_ftype_ushort_unsigned_ushort;
+ break;
+ case UCHAR_FTYPE_UINT_UINT_UINT:
+ type = uchar_ftype_unsigned_unsigned_unsigned;
+ break;
+ case UCHAR_FTYPE_UINT64_UINT_UINT:
+ type = uchar_ftype_uint64_unsigned_unsigned;
+ break;
+
default:
gcc_unreachable ();
}
@@ -24803,7 +25412,7 @@ ix86_expand_special_args_builtin (const struct builtin_description *d,
{
rtx op;
enum machine_mode mode;
- } args[2];
+ } args[3];
enum insn_code icode = d->icode;
bool last_arg_constant = false;
const struct insn_data *insn_p = &insn_data[icode];
@@ -24824,6 +25433,7 @@ ix86_expand_special_args_builtin (const struct builtin_description *d,
case V4DF_FTYPE_PCV2DF:
case V4DF_FTYPE_PCDOUBLE:
case V2DF_FTYPE_PCDOUBLE:
+ case VOID_FTYPE_PVOID:
nargs = 1;
klass = load;
memory = 0;
@@ -24867,6 +25477,15 @@ ix86_expand_special_args_builtin (const struct builtin_description *d,
/* Reserve memory operand for target. */
memory = ARRAY_SIZE (args);
break;
+ case VOID_FTYPE_UINT_UINT_UINT:
+ case VOID_FTYPE_UINT64_UINT_UINT:
+ case UCHAR_FTYPE_UINT_UINT_UINT:
+ case UCHAR_FTYPE_UINT64_UINT_UINT:
+ nargs = 3;
+ klass = load;
+ memory = ARRAY_SIZE (args);
+ last_arg_constant = true;
+ break;
default:
gcc_unreachable ();
}
@@ -24903,12 +25522,16 @@ ix86_expand_special_args_builtin (const struct builtin_description *d,
if (last_arg_constant && (i + 1) == nargs)
{
if (!match)
- switch (icode)
- {
- default:
+ {
+ if (icode == CODE_FOR_lwp_lwpvalsi3
+ || icode == CODE_FOR_lwp_lwpinssi3
+ || icode == CODE_FOR_lwp_lwpvaldi3
+ || icode == CODE_FOR_lwp_lwpinsdi3)
+ error ("the last argument must be a 32-bit immediate");
+ else
error ("the last argument must be an 8-bit immediate");
- return const0_rtx;
- }
+ return const0_rtx;
+ }
}
else
{
@@ -24943,6 +25566,9 @@ ix86_expand_special_args_builtin (const struct builtin_description *d,
case 2:
pat = GEN_FCN (icode) (target, args[0].op, args[1].op);
break;
+ case 3:
+ pat = GEN_FCN (icode) (target, args[0].op, args[1].op, args[2].op);
+ break;
default:
gcc_unreachable ();
}
@@ -25240,6 +25866,23 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
return target;
}
+ case IX86_BUILTIN_LLWPCB:
+ arg0 = CALL_EXPR_ARG (exp, 0);
+ op0 = expand_normal (arg0);
+ icode = CODE_FOR_lwp_llwpcb;
+ if (! (*insn_data[icode].operand[0].predicate) (op0, Pmode))
+ op0 = copy_to_mode_reg (Pmode, op0);
+ emit_insn (gen_lwp_llwpcb (op0));
+ return 0;
+
+ case IX86_BUILTIN_SLWPCB:
+ icode = CODE_FOR_lwp_slwpcb;
+ if (!target
+ || ! (*insn_data[icode].operand[0].predicate) (target, Pmode))
+ target = gen_reg_rtx (Pmode);
+ emit_insn (gen_lwp_slwpcb (target));
+ return target;
+
default:
break;
}
@@ -29840,14 +30483,11 @@ x86_builtin_vectorization_cost (bool runtime_test)
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)
+ if (ix86_function_abi ((const_tree) fndecl) == MS_ABI)
return ms_va_list_type_node;
else
return sysv_va_list_type_node;
diff --git a/gcc-4.4.3/gcc/config/i386/i386.h b/gcc-4.4.3/gcc/config/i386/i386.h
index abdc7d019..e9014b79a 100644
--- a/gcc-4.4.3/gcc/config/i386/i386.h
+++ b/gcc-4.4.3/gcc/config/i386/i386.h
@@ -55,10 +55,12 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#define TARGET_FMA OPTION_ISA_FMA
#define TARGET_SSE4A OPTION_ISA_SSE4A
#define TARGET_SSE5 OPTION_ISA_SSE5
+#define TARGET_LWP OPTION_ISA_LWP
#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_MOVBE OPTION_ISA_MOVBE
#define TARGET_AES OPTION_ISA_AES
#define TARGET_PCLMUL OPTION_ISA_PCLMUL
#define TARGET_CMPXCHG16B OPTION_ISA_CX16
@@ -236,6 +238,7 @@ extern const struct processor_costs ix86_size_cost;
#define TARGET_GENERIC64 (ix86_tune == PROCESSOR_GENERIC64)
#define TARGET_GENERIC (TARGET_GENERIC32 || TARGET_GENERIC64)
#define TARGET_AMDFAM10 (ix86_tune == PROCESSOR_AMDFAM10)
+#define TARGET_ATOM (ix86_tune == PROCESSOR_ATOM)
/* Feature tests against the various tunings. */
enum ix86_tune_indices {
@@ -300,6 +303,7 @@ enum ix86_tune_indices {
X86_TUNE_USE_VECTOR_FP_CONVERTS,
X86_TUNE_USE_VECTOR_CONVERTS,
X86_TUNE_FUSE_CMP_AND_BRANCH,
+ X86_TUNE_OPT_AGU,
X86_TUNE_LAST
};
@@ -387,6 +391,7 @@ extern unsigned char ix86_tune_features[X86_TUNE_LAST];
ix86_tune_features[X86_TUNE_USE_VECTOR_CONVERTS]
#define TARGET_FUSE_CMP_AND_BRANCH \
ix86_tune_features[X86_TUNE_FUSE_CMP_AND_BRANCH]
+#define TARGET_OPT_AGU ix86_tune_features[X86_TUNE_OPT_AGU]
/* Feature tests against the various architecture variations. */
enum ix86_arch_indices {
@@ -470,7 +475,10 @@ enum calling_abi
MS_ABI = 1
};
-/* The default abi form used by target. */
+/* The abi used by target. */
+extern enum calling_abi ix86_abi;
+
+/* The default abi used by target. */
#define DEFAULT_ABI SYSV_ABI
/* Subtargets may reset this to 1 in order to enable 96-bit long double
@@ -569,6 +577,7 @@ enum target_cpu_default
TARGET_CPU_DEFAULT_prescott,
TARGET_CPU_DEFAULT_nocona,
TARGET_CPU_DEFAULT_core2,
+ TARGET_CPU_DEFAULT_atom,
TARGET_CPU_DEFAULT_geode,
TARGET_CPU_DEFAULT_k6,
@@ -658,7 +667,7 @@ enum target_cpu_default
/* Boundary (in *bits*) on which stack pointer should be aligned. */
#define STACK_BOUNDARY \
- (TARGET_64BIT && DEFAULT_ABI == MS_ABI ? 128 : BITS_PER_WORD)
+ (TARGET_64BIT && ix86_abi == MS_ABI ? 128 : BITS_PER_WORD)
/* Stack boundary of the main function guaranteed by OS. */
#define MAIN_STACK_BOUNDARY (TARGET_64BIT ? 128 : 32)
@@ -679,9 +688,7 @@ enum target_cpu_default
generate an alternate prologue and epilogue that realigns the
runtime stack if nessary. This supports mixing codes that keep a
4-byte aligned stack, as specified by i386 psABI, with codes that
- need a 16-byte aligned stack, as required by SSE instructions. If
- STACK_REALIGN_DEFAULT is 1 and PREFERRED_STACK_BOUNDARY_DEFAULT is
- 128, stacks for all functions may be realigned. */
+ need a 16-byte aligned stack, as required by SSE instructions. */
#define STACK_REALIGN_DEFAULT 0
/* Boundary (in *bits*) on which the incoming stack is aligned. */
@@ -1584,7 +1591,7 @@ typedef struct ix86_args {
int maybe_vaarg; /* true for calls to possibly vardic fncts. */
int float_in_sse; /* 1 if in 32-bit mode SFmode (2 for DFmode) should
be passed in SSE registers. Otherwise 0. */
- int call_abi; /* Set to SYSV_ABI for sysv abi. Otherwise
+ enum calling_abi call_abi; /* Set to SYSV_ABI for sysv abi. Otherwise
MS_ABI for ms abi. */
} CUMULATIVE_ARGS;
@@ -2230,6 +2237,7 @@ enum processor_type
PROCESSOR_GENERIC32,
PROCESSOR_GENERIC64,
PROCESSOR_AMDFAM10,
+ PROCESSOR_ATOM,
PROCESSOR_max
};
@@ -2410,7 +2418,7 @@ struct machine_function GTY(())
int tls_descriptor_call_expanded_p;
/* This value is used for amd64 targets and specifies the current abi
to be used. MS_ABI means ms abi. Otherwise SYSV_ABI means sysv abi. */
- int call_abi;
+ enum calling_abi call_abi;
struct machine_cfa_state cfa;
};
#endif
diff --git a/gcc-4.4.3/gcc/config/i386/i386.md b/gcc-4.4.3/gcc/config/i386/i386.md
index 22c891c49..bbe915112 100644
--- a/gcc-4.4.3/gcc/config/i386/i386.md
+++ b/gcc-4.4.3/gcc/config/i386/i386.md
@@ -227,6 +227,11 @@
(UNSPECV_CLD 15)
(UNSPECV_VZEROALL 16)
(UNSPECV_VZEROUPPER 17)
+ (UNSPECV_VSWAPMOV 18)
+ (UNSPECV_LLWP_INTRINSIC 19)
+ (UNSPECV_SLWP_INTRINSIC 20)
+ (UNSPECV_LWPVAL_INTRINSIC 21)
+ (UNSPECV_LWPINS_INTRINSIC 22)
])
;; Constants to represent pcomtrue/pcomfalse variants
@@ -315,7 +320,7 @@
;; Processor type.
-(define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,
+(define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,atom,
generic64,amdfam10"
(const (symbol_ref "ix86_schedule")))
@@ -329,9 +334,9 @@
push,pop,call,callv,leave,
str,bitmanip,
fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
- sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
+ sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
- ssemuladd,sse4arg,
+ ssemuladd,sse4arg,lwp,
mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
(const_string "other"))
@@ -344,7 +349,7 @@
(define_attr "unit" "integer,i387,sse,mmx,unknown"
(cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
(const_string "i387")
- (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
+ (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
(const_string "sse")
@@ -524,7 +529,7 @@
;; if the instruction is complex.
(define_attr "memory" "none,load,store,both,unknown"
- (cond [(eq_attr "type" "other,multi,str")
+ (cond [(eq_attr "type" "other,multi,str,lwp")
(const_string "unknown")
(eq_attr "type" "lea,fcmov,fpspc")
(const_string "none")
@@ -611,6 +616,12 @@
(define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
(const_string "any"))
+;; Define attribute to classify add/sub insns that consumes carry flag (CF)
+(define_attr "use_carry" "0,1" (const_string "0"))
+
+;; Define attribute to indicate unaligned ssemov insns
+(define_attr "movu" "0,1" (const_string "0"))
+
;; Describe a user's asm statement.
(define_asm_attributes
[(set_attr "length" "128")
@@ -673,6 +684,9 @@
;; Single word integer modes without QImode.
(define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
+;; Single word integer modes without QImode and HImode.
+(define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
+
;; Instruction suffix for integer modes.
(define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
@@ -726,6 +740,7 @@
(include "k6.md")
(include "athlon.md")
(include "geode.md")
+(include "atom.md")
;; Operand and operator predicates and constraints
@@ -5789,6 +5804,7 @@
"TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
"adc{q}\t{%2, %0|%0, %2}"
[(set_attr "type" "alu")
+ (set_attr "use_carry" "1")
(set_attr "pent_pair" "pu")
(set_attr "mode" "DI")])
@@ -5863,6 +5879,7 @@
"ix86_binary_operator_ok (PLUS, QImode, operands)"
"adc{b}\t{%2, %0|%0, %2}"
[(set_attr "type" "alu")
+ (set_attr "use_carry" "1")
(set_attr "pent_pair" "pu")
(set_attr "mode" "QI")])
@@ -5875,6 +5892,7 @@
"ix86_binary_operator_ok (PLUS, HImode, operands)"
"adc{w}\t{%2, %0|%0, %2}"
[(set_attr "type" "alu")
+ (set_attr "use_carry" "1")
(set_attr "pent_pair" "pu")
(set_attr "mode" "HI")])
@@ -5887,6 +5905,7 @@
"ix86_binary_operator_ok (PLUS, SImode, operands)"
"adc{l}\t{%2, %0|%0, %2}"
[(set_attr "type" "alu")
+ (set_attr "use_carry" "1")
(set_attr "pent_pair" "pu")
(set_attr "mode" "SI")])
@@ -5900,6 +5919,7 @@
"TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
"adc{l}\t{%2, %k0|%k0, %2}"
[(set_attr "type" "alu")
+ (set_attr "use_carry" "1")
(set_attr "pent_pair" "pu")
(set_attr "mode" "SI")])
@@ -6129,9 +6149,9 @@
(set_attr "mode" "SI")])
(define_insn "*adddi_1_rex64"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
- (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
- (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
+ (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r,r")
+ (match_operand:DI 2 "x86_64_general_operand" "rme,re,0,le")))
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
{
@@ -6152,6 +6172,10 @@
}
default:
+ /* Use add as much as possible to replace lea for AGU optimization. */
+ if (which_alternative == 2 && TARGET_OPT_AGU)
+ return "add{q}\t{%1, %0|%0, %1}";
+
gcc_assert (rtx_equal_p (operands[0], operands[1]));
/* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
@@ -6170,8 +6194,11 @@
}
}
[(set (attr "type")
- (cond [(eq_attr "alternative" "2")
+ (cond [(and (eq_attr "alternative" "2")
+ (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
(const_string "lea")
+ (eq_attr "alternative" "3")
+ (const_string "lea")
; Current assemblers are broken and do not allow @GOTOFF in
; ought but a memory context.
(match_operand:DI 2 "pic_symbolic_operand" "")
@@ -6188,8 +6215,8 @@
(plus:DI (match_operand:DI 1 "register_operand" "")
(match_operand:DI 2 "x86_64_nonmemory_operand" "")))
(clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT && reload_completed
- && true_regnum (operands[0]) != true_regnum (operands[1])"
+ "TARGET_64BIT && reload_completed
+ && ix86_lea_for_add_ok (PLUS, insn, operands)"
[(set (match_dup 0)
(plus:DI (match_dup 1)
(match_dup 2)))]
@@ -6393,9 +6420,9 @@
(define_insn "*addsi_1"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
- (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
- (match_operand:SI 2 "general_operand" "g,ri,li")))
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r,r")
+ (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r,r")
+ (match_operand:SI 2 "general_operand" "g,ri,0,li")))
(clobber (reg:CC FLAGS_REG))]
"ix86_binary_operator_ok (PLUS, SImode, operands)"
{
@@ -6416,6 +6443,10 @@
}
default:
+ /* Use add as much as possible to replace lea for AGU optimization. */
+ if (which_alternative == 2 && TARGET_OPT_AGU)
+ return "add{l}\t{%1, %0|%0, %1}";
+
gcc_assert (rtx_equal_p (operands[0], operands[1]));
/* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
@@ -6432,7 +6463,10 @@
}
}
[(set (attr "type")
- (cond [(eq_attr "alternative" "2")
+ (cond [(and (eq_attr "alternative" "2")
+ (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
+ (const_string "lea")
+ (eq_attr "alternative" "3")
(const_string "lea")
; Current assemblers are broken and do not allow @GOTOFF in
; ought but a memory context.
@@ -6450,8 +6484,7 @@
(plus (match_operand 1 "register_operand" "")
(match_operand 2 "nonmemory_operand" "")))
(clobber (reg:CC FLAGS_REG))]
- "reload_completed
- && true_regnum (operands[0]) != true_regnum (operands[1])"
+ "reload_completed && ix86_lea_for_add_ok (PLUS, insn, operands)"
[(const_int 0)]
{
rtx pat;
@@ -7552,6 +7585,7 @@
"TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
"sbb{q}\t{%2, %0|%0, %2}"
[(set_attr "type" "alu")
+ (set_attr "use_carry" "1")
(set_attr "pent_pair" "pu")
(set_attr "mode" "DI")])
@@ -7600,6 +7634,7 @@
"ix86_binary_operator_ok (MINUS, QImode, operands)"
"sbb{b}\t{%2, %0|%0, %2}"
[(set_attr "type" "alu")
+ (set_attr "use_carry" "1")
(set_attr "pent_pair" "pu")
(set_attr "mode" "QI")])
@@ -7612,6 +7647,7 @@
"ix86_binary_operator_ok (MINUS, HImode, operands)"
"sbb{w}\t{%2, %0|%0, %2}"
[(set_attr "type" "alu")
+ (set_attr "use_carry" "1")
(set_attr "pent_pair" "pu")
(set_attr "mode" "HI")])
@@ -7624,6 +7660,7 @@
"ix86_binary_operator_ok (MINUS, SImode, operands)"
"sbb{l}\t{%2, %0|%0, %2}"
[(set_attr "type" "alu")
+ (set_attr "use_carry" "1")
(set_attr "pent_pair" "pu")
(set_attr "mode" "SI")])
@@ -15162,7 +15199,7 @@
? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
operands[0], const0_rtx,
GEN_INT ((TARGET_64BIT
- ? (DEFAULT_ABI == SYSV_ABI
+ ? (ix86_abi == SYSV_ABI
? X86_64_SSE_REGPARM_MAX
: X64_SSE_REGPARM_MAX)
: X86_32_SSE_REGPARM_MAX)
@@ -15242,6 +15279,7 @@
"reload_completed"
"ret"
[(set_attr "length" "1")
+ (set_attr "atom_unit" "jeu")
(set_attr "length_immediate" "0")
(set_attr "modrm" "0")])
@@ -15254,6 +15292,7 @@
"reload_completed"
"rep\;ret"
[(set_attr "length" "1")
+ (set_attr "atom_unit" "jeu")
(set_attr "length_immediate" "0")
(set_attr "prefix_rep" "1")
(set_attr "modrm" "0")])
@@ -15264,6 +15303,7 @@
"reload_completed"
"ret\t%0"
[(set_attr "length" "3")
+ (set_attr "atom_unit" "jeu")
(set_attr "length_immediate" "2")
(set_attr "modrm" "0")])
@@ -15612,7 +15652,7 @@
(bswap:SI (match_operand:SI 1 "register_operand" "")))]
""
{
- if (!TARGET_BSWAP)
+ if (!(TARGET_BSWAP || TARGET_MOVBE))
{
rtx x = operands[0];
@@ -15624,6 +15664,21 @@
}
})
+(define_insn "*bswapsi_movbe"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m")
+ (bswap:SI (match_operand:SI 1 "nonimmediate_operand" "0,m,r")))]
+ "TARGET_MOVBE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
+ "@
+ bswap\t%0
+ movbe\t{%1, %0|%0, %1}
+ movbe\t{%1, %0|%0, %1}"
+ [(set_attr "type" "*,imov,imov")
+ (set_attr "modrm" "*,1,1")
+ (set_attr "prefix_0f" "1")
+ (set_attr "prefix_extra" "*,1,1")
+ (set_attr "length" "2,*,*")
+ (set_attr "mode" "SI")])
+
(define_insn "*bswapsi_1"
[(set (match_operand:SI 0 "register_operand" "=r")
(bswap:SI (match_operand:SI 1 "register_operand" "0")))]
@@ -15652,7 +15707,29 @@
[(set_attr "length" "4")
(set_attr "mode" "HI")])
-(define_insn "bswapdi2"
+(define_expand "bswapdi2"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (bswap:DI (match_operand:DI 1 "register_operand" "")))]
+ "TARGET_64BIT"
+ "")
+
+(define_insn "*bswapdi_movbe"
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
+ (bswap:DI (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))]
+ "TARGET_64BIT && TARGET_MOVBE
+ && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
+ "@
+ bswap\t%0
+ movbe\t{%1, %0|%0, %1}
+ movbe\t{%1, %0|%0, %1}"
+ [(set_attr "type" "*,imov,imov")
+ (set_attr "modrm" "*,1,1")
+ (set_attr "prefix_0f" "1")
+ (set_attr "prefix_extra" "*,1,1")
+ (set_attr "length" "3,*,*")
+ (set_attr "mode" "DI")])
+
+(define_insn "*bswapdi_1"
[(set (match_operand:DI 0 "register_operand" "=r")
(bswap:DI (match_operand:DI 1 "register_operand" "0")))]
"TARGET_64BIT"
@@ -16380,6 +16457,7 @@
"TARGET_SSE_MATH"
"%vrcpss\t{%1, %d0|%d0, %1}"
[(set_attr "type" "sse")
+ (set_attr "atom_sse_attr" "rcp")
(set_attr "prefix" "maybe_vex")
(set_attr "mode" "SF")])
@@ -16731,6 +16809,7 @@
"TARGET_SSE_MATH"
"%vrsqrtss\t{%1, %d0|%d0, %1}"
[(set_attr "type" "sse")
+ (set_attr "atom_sse_attr" "rcp")
(set_attr "prefix" "maybe_vex")
(set_attr "mode" "SF")])
@@ -16751,6 +16830,7 @@
"SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
"%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
[(set_attr "type" "sse")
+ (set_attr "atom_sse_attr" "sqrt")
(set_attr "prefix" "maybe_vex")
(set_attr "mode" "<MODE>")
(set_attr "athlon_decode" "*")
@@ -19807,6 +19887,7 @@
; Since we don't have the proper number of operands for an alu insn,
; fill in all the blanks.
[(set_attr "type" "alu")
+ (set_attr "use_carry" "1")
(set_attr "pent_pair" "pu")
(set_attr "memory" "none")
(set_attr "imm_disp" "false")
@@ -19822,6 +19903,7 @@
""
"sbb{q}\t%0, %0"
[(set_attr "type" "alu")
+ (set_attr "use_carry" "1")
(set_attr "pent_pair" "pu")
(set_attr "memory" "none")
(set_attr "imm_disp" "false")
@@ -19865,6 +19947,7 @@
; Since we don't have the proper number of operands for an alu insn,
; fill in all the blanks.
[(set_attr "type" "alu")
+ (set_attr "use_carry" "1")
(set_attr "pent_pair" "pu")
(set_attr "memory" "none")
(set_attr "imm_disp" "false")
@@ -19880,6 +19963,7 @@
""
"sbb{l}\t%0, %0"
[(set_attr "type" "alu")
+ (set_attr "use_carry" "1")
(set_attr "pent_pair" "pu")
(set_attr "memory" "none")
(set_attr "imm_disp" "false")
@@ -20212,7 +20296,8 @@
}
}
[(set (attr "type")
- (cond [(eq_attr "alternative" "0")
+ (cond [(and (eq_attr "alternative" "0")
+ (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
(const_string "alu")
(match_operand:SI 2 "const0_operand" "")
(const_string "imov")
@@ -20255,7 +20340,8 @@
}
}
[(set (attr "type")
- (cond [(eq_attr "alternative" "0")
+ (cond [(and (eq_attr "alternative" "0")
+ (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
(const_string "alu")
(match_operand:DI 2 "const0_operand" "")
(const_string "imov")
@@ -21753,6 +21839,7 @@
return patterns[locality];
}
[(set_attr "type" "sse")
+ (set_attr "atom_sse_attr" "prefetch")
(set_attr "memory" "none")])
(define_insn "*prefetch_sse_rex"
@@ -21771,6 +21858,7 @@
return patterns[locality];
}
[(set_attr "type" "sse")
+ (set_attr "atom_sse_attr" "prefetch")
(set_attr "memory" "none")])
(define_insn "*prefetch_3dnow"
@@ -21972,6 +22060,93 @@
(set_attr "prefix_extra" "1")
(set_attr "mode" "DI")])
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; LWP instructions
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(define_expand "lwp_llwpcb"
+ [(unspec_volatile [(match_operand 0 "register_operand" "r")]
+ UNSPECV_LLWP_INTRINSIC)]
+ "TARGET_LWP"
+ "")
+
+(define_insn "*lwp_llwpcb<mode>1"
+ [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
+ UNSPECV_LLWP_INTRINSIC)]
+ "TARGET_LWP"
+ "llwpcb\t%0"
+ [(set_attr "type" "lwp")
+ (set_attr "mode" "<MODE>")
+ (set_attr "length" "5")])
+
+(define_expand "lwp_slwpcb"
+ [(set (match_operand 0 "register_operand" "=r")
+ (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
+ "TARGET_LWP"
+ {
+ if (TARGET_64BIT)
+ emit_insn (gen_lwp_slwpcbdi (operands[0]));
+ else
+ emit_insn (gen_lwp_slwpcbsi (operands[0]));
+ DONE;
+ })
+
+(define_insn "lwp_slwpcb<mode>"
+ [(set (match_operand:P 0 "register_operand" "=r")
+ (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
+ "TARGET_LWP"
+ "slwpcb\t%0"
+ [(set_attr "type" "lwp")
+ (set_attr "mode" "<MODE>")
+ (set_attr "length" "5")])
+
+(define_expand "lwp_lwpval<mode>3"
+ [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
+ (match_operand:SI 2 "nonimmediate_operand" "rm")
+ (match_operand:SI 3 "const_int_operand" "i")]
+ UNSPECV_LWPVAL_INTRINSIC)]
+ "TARGET_LWP"
+ "/* Avoid unused variable warning. */
+ (void) operand0;")
+
+(define_insn "*lwp_lwpval<mode>3_1"
+ [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
+ (match_operand:SI 1 "nonimmediate_operand" "rm")
+ (match_operand:SI 2 "const_int_operand" "i")]
+ UNSPECV_LWPVAL_INTRINSIC)]
+ "TARGET_LWP"
+ "lwpval\t{%2, %1, %0|%0, %1, %2}"
+ [(set_attr "type" "lwp")
+ (set_attr "mode" "<MODE>")
+ (set (attr "length")
+ (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
+
+(define_expand "lwp_lwpins<mode>3"
+ [(set (reg:CCC FLAGS_REG)
+ (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
+ (match_operand:SI 2 "nonimmediate_operand" "rm")
+ (match_operand:SI 3 "const_int_operand" "i")]
+ UNSPECV_LWPINS_INTRINSIC))
+ (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
+ (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
+ "TARGET_LWP"
+ "")
+
+(define_insn "*lwp_lwpins<mode>3_1"
+ [(set (reg:CCC FLAGS_REG)
+ (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
+ (match_operand:SI 1 "nonimmediate_operand" "rm")
+ (match_operand:SI 2 "const_int_operand" "i")]
+ UNSPECV_LWPINS_INTRINSIC))]
+ "TARGET_LWP"
+ "lwpins\t{%2, %1, %0|%0, %1, %2}"
+ [(set_attr "type" "lwp")
+ (set_attr "mode" "<MODE>")
+ (set (attr "length")
+ (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
+
(include "mmx.md")
(include "sse.md")
(include "sync.md")
diff --git a/gcc-4.4.3/gcc/config/i386/i386.opt b/gcc-4.4.3/gcc/config/i386/i386.opt
index 05727be7b..c2562e48d 100644
--- a/gcc-4.4.3/gcc/config/i386/i386.opt
+++ b/gcc-4.4.3/gcc/config/i386/i386.opt
@@ -232,6 +232,10 @@ mtune=
Target RejectNegative Joined Var(ix86_tune_string)
Schedule code for given CPU
+mabi=
+Target RejectNegative Joined Var(ix86_abi_string)
+Generate code that conforms to the given ABI
+
mveclibabi=
Target RejectNegative Joined Var(ix86_veclibabi_string)
Vector library ABI to use
@@ -323,6 +327,10 @@ msse5
Target Report Mask(ISA_SSE5) Var(ix86_isa_flags) VarExists Save
Support SSE5 built-in functions and code generation
+mlwp
+Target Report Mask(ISA_LWP) Var(ix86_isa_flags) VarExists Save
+Support LWP built-in functions and code generation
+
mabm
Target Report Mask(ISA_ABM) Var(ix86_isa_flags) VarExists Save
Support code generation of Advanced Bit Manipulation (ABM) instructions.
@@ -339,6 +347,10 @@ msahf
Target Report Mask(ISA_SAHF) Var(ix86_isa_flags) VarExists Save
Support code generation of sahf instruction in 64bit x86-64 code.
+mmovbe
+Target Report Mask(ISA_MOVBE) Var(ix86_isa_flags) VarExists Save
+Support code generation of movbe instruction.
+
maes
Target Report Mask(ISA_AES) Var(ix86_isa_flags) VarExists Save
Support AES built-in functions and code generation
diff --git a/gcc-4.4.3/gcc/config/i386/linux-unwind.h b/gcc-4.4.3/gcc/config/i386/linux-unwind.h
index 89f238a6e..d73f354ba 100644
--- a/gcc-4.4.3/gcc/config/i386/linux-unwind.h
+++ b/gcc-4.4.3/gcc/config/i386/linux-unwind.h
@@ -106,7 +106,7 @@ x86_64_fallback_frame_state (struct _Unwind_Context *context,
signal-turned-exceptions for them. There's also no configure-run for
the target, so we can't check on (e.g.) HAVE_SYS_UCONTEXT_H. Using the
target libc version macro should be enough. */
-#if !(__GLIBC__ == 2 && __GLIBC_MINOR__ == 0)
+#if defined __GLIBC__ && !(__GLIBC__ == 2 && __GLIBC_MINOR__ == 0)
#include <signal.h>
#include <sys/ucontext.h>
diff --git a/gcc-4.4.3/gcc/config/i386/linux.h b/gcc-4.4.3/gcc/config/i386/linux.h
index 4f19b20ea..f3a98c26a 100644
--- a/gcc-4.4.3/gcc/config/i386/linux.h
+++ b/gcc-4.4.3/gcc/config/i386/linux.h
@@ -107,7 +107,7 @@ along with GCC; see the file COPYING3. If not see
#undef ASM_SPEC
#define ASM_SPEC \
- "%{v:-V} %{Qy:} %{!Qn:-Qy} %{n} %{T} %{Ym,*} %{Yd,*} %{Wa,*:%*} \
+ "%{v:-V} %{Qy:} %{!Qn:-Qy} %{n} %{T} %{Ym,*} %{Yd,*} %{Wa,*:%*} --32 \
%{!mno-sse2avx:%{mavx:-msse2avx}} %{msse2avx:%{!mavx:-msse2avx}}"
/* These may be provided by config/linux-grtev2.h. */
diff --git a/gcc-4.4.3/gcc/config/i386/linux64.h b/gcc-4.4.3/gcc/config/i386/linux64.h
index 9fe1d0aca..17d972cfb 100644
--- a/gcc-4.4.3/gcc/config/i386/linux64.h
+++ b/gcc-4.4.3/gcc/config/i386/linux64.h
@@ -64,11 +64,6 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#define GLIBC_DYNAMIC_LINKER32 RUNTIME_ROOT_PREFIX "/lib/ld-linux.so.2"
#define GLIBC_DYNAMIC_LINKER64 RUNTIME_ROOT_PREFIX "/lib64/ld-linux-x86-64.so.2"
-#undef ASM_SPEC
-#define ASM_SPEC "%{v:-V} %{Qy:} %{!Qn:-Qy} %{n} %{T} %{Ym,*} %{Yd,*} \
- %{Wa,*:%*} %{m32:--32} %{m64:--64} \
- %{!mno-sse2avx:%{mavx:-msse2avx}} %{msse2avx:%{!mavx:-msse2avx}}"
-
#if TARGET_64BIT_DEFAULT
#define SPEC_32 "m32"
#define SPEC_64 "!m32"
@@ -77,6 +72,11 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#define SPEC_64 "m64"
#endif
+#undef ASM_SPEC
+#define ASM_SPEC "%{v:-V} %{Qy:} %{!Qn:-Qy} %{n} %{T} %{Ym,*} %{Yd,*} \
+ %{Wa,*:%*} %{" SPEC_32 ":--32} %{" SPEC_64 ":--64} \
+ %{!mno-sse2avx:%{mavx:-msse2avx}} %{msse2avx:%{!mavx:-msse2avx}}"
+
#undef LINK_SPEC
#define LINK_SPEC "%{" SPEC_64 ":-m elf_x86_64} %{" SPEC_32 ":-m elf_i386} \
%{shared:-shared} \
diff --git a/gcc-4.4.3/gcc/config/i386/lwpintrin.h b/gcc-4.4.3/gcc/config/i386/lwpintrin.h
new file mode 100644
index 000000000..954b039e5
--- /dev/null
+++ b/gcc-4.4.3/gcc/config/i386/lwpintrin.h
@@ -0,0 +1,100 @@
+/* Copyright (C) 2007, 2008, 2009 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.
+
+ Under Section 7 of GPL version 3, you are granted additional
+ permissions described in the GCC Runtime Library Exception, version
+ 3.1, as published by the Free Software Foundation.
+
+ You should have received a copy of the GNU General Public License and
+ a copy of the GCC Runtime Library Exception along with this program;
+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _X86INTRIN_H_INCLUDED
+# error "Never use <lwpintrin.h> directly; include <x86intrin.h> instead."
+#endif
+
+#ifndef _LWPINTRIN_H_INCLUDED
+#define _LWPINTRIN_H_INCLUDED
+
+#ifndef __LWP__
+# error "LWP instruction set not enabled"
+#else
+
+extern __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+__llwpcb (void *pcbAddress)
+{
+ __builtin_ia32_llwpcb (pcbAddress);
+}
+
+extern __inline void * __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+__slwpcb (void)
+{
+ return __builtin_ia32_slwpcb ();
+}
+
+#ifdef __OPTIMIZE__
+extern __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+__lwpval32 (unsigned int data2, unsigned int data1, unsigned int flags)
+{
+ __builtin_ia32_lwpval32 (data2, data1, flags);
+}
+
+#ifdef __x86_64__
+extern __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+__lwpval64 (unsigned long long data2, unsigned int data1, unsigned int flags)
+{
+ __builtin_ia32_lwpval64 (data2, data1, flags);
+}
+#endif
+#else
+#define __lwpval32(D2, D1, F) \
+ (__builtin_ia32_lwpval32 ((unsigned int) (D2), (unsigned int) (D1), \
+ (unsigned int) (F)))
+#ifdef __x86_64__
+#define __lwpval64(D2, D1, F) \
+ (__builtin_ia32_lwpval64 ((unsigned long long) (D2), (unsigned int) (D1), \
+ (unsigned int) (F)))
+#endif
+#endif
+
+
+#ifdef __OPTIMIZE__
+extern __inline unsigned char __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+__lwpins32 (unsigned int data2, unsigned int data1, unsigned int flags)
+{
+ return __builtin_ia32_lwpins32 (data2, data1, flags);
+}
+
+#ifdef __x86_64__
+extern __inline unsigned char __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+__lwpins64 (unsigned long long data2, unsigned int data1, unsigned int flags)
+{
+ return __builtin_ia32_lwpins64 (data2, data1, flags);
+}
+#endif
+#else
+#define __lwpins32(D2, D1, F) \
+ (__builtin_ia32_lwpins32 ((unsigned int) (D2), (unsigned int) (D1), \
+ (unsigned int) (F)))
+#ifdef __x86_64__
+#define __lwpins64(D2, D1, F) \
+ (__builtin_ia32_lwpins64 ((unsigned long long) (D2), (unsigned int) (D1), \
+ (unsigned int) (F)))
+#endif
+#endif
+
+#endif /* __LWP__ */
+
+#endif /* _LWPINTRIN_H_INCLUDED */
diff --git a/gcc-4.4.3/gcc/config/i386/mingw32.h b/gcc-4.4.3/gcc/config/i386/mingw32.h
index f3fbe8c58..746d7d105 100644
--- a/gcc-4.4.3/gcc/config/i386/mingw32.h
+++ b/gcc-4.4.3/gcc/config/i386/mingw32.h
@@ -38,7 +38,7 @@ along with GCC; see the file COPYING3. If not see
builtin_define_std ("WINNT"); \
builtin_define_with_int_value ("_INTEGRAL_MAX_BITS", \
TYPE_PRECISION (intmax_type_node));\
- if (TARGET_64BIT && DEFAULT_ABI == MS_ABI) \
+ if (TARGET_64BIT && ix86_abi == MS_ABI) \
{ \
builtin_define ("__MINGW64__"); \
builtin_define_std ("WIN64"); \
diff --git a/gcc-4.4.3/gcc/config/i386/ppro.md b/gcc-4.4.3/gcc/config/i386/ppro.md
index 5e163d829..20f457ab1 100644
--- a/gcc-4.4.3/gcc/config/i386/ppro.md
+++ b/gcc-4.4.3/gcc/config/i386/ppro.md
@@ -731,7 +731,7 @@
(define_insn_reservation "ppro_insn" 1
(and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "none,unknown")
- (eq_attr "type" "alu,alu1,negnot,incdec,icmp,test,setcc,icmov,push,pop,fxch,sseiadd,sseishft,sseimul,mmx,mmxadd,mmxcmp")))
+ (eq_attr "type" "alu,alu1,negnot,incdec,icmp,test,setcc,icmov,push,pop,fxch,sseiadd,sseishft,sseishft1,sseimul,mmx,mmxadd,mmxcmp")))
"decodern,(p0|p1)")
;; read-modify and register-memory instructions have 2 or three uops,
@@ -739,13 +739,13 @@
(define_insn_reservation "ppro_insn_load" 3
(and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "load")
- (eq_attr "type" "alu,alu1,negnot,incdec,icmp,test,setcc,icmov,push,pop,fxch,sseiadd,sseishft,sseimul,mmx,mmxadd,mmxcmp")))
+ (eq_attr "type" "alu,alu1,negnot,incdec,icmp,test,setcc,icmov,push,pop,fxch,sseiadd,sseishft,sseishft1,sseimul,mmx,mmxadd,mmxcmp")))
"decoder0,p2+(p0|p1)")
(define_insn_reservation "ppro_insn_store" 1
(and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "store")
- (eq_attr "type" "alu,alu1,negnot,incdec,icmp,test,setcc,icmov,push,pop,fxch,sseiadd,sseishft,sseimul,mmx,mmxadd,mmxcmp")))
+ (eq_attr "type" "alu,alu1,negnot,incdec,icmp,test,setcc,icmov,push,pop,fxch,sseiadd,sseishft,sseishft1,sseimul,mmx,mmxadd,mmxcmp")))
"decoder0,(p0|p1),p4+p3")
;; read-modify-store instructions produce 4 uops so they have to be
@@ -753,6 +753,6 @@
(define_insn_reservation "ppro_insn_both" 4
(and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "both")
- (eq_attr "type" "alu,alu1,negnot,incdec,icmp,test,setcc,icmov,push,pop,fxch,sseiadd,sseishft,sseimul,mmx,mmxadd,mmxcmp")))
+ (eq_attr "type" "alu,alu1,negnot,incdec,icmp,test,setcc,icmov,push,pop,fxch,sseiadd,sseishft,sseishft1,sseimul,mmx,mmxadd,mmxcmp")))
"decoder0,p2+(p0|p1),p4+p3")
diff --git a/gcc-4.4.3/gcc/config/i386/sse.md b/gcc-4.4.3/gcc/config/i386/sse.md
index ea5fb3440..cae9eed3b 100644
--- a/gcc-4.4.3/gcc/config/i386/sse.md
+++ b/gcc-4.4.3/gcc/config/i386/sse.md
@@ -342,6 +342,7 @@
&& !(MEM_P (operands[0]) && MEM_P (operands[1]))"
"vmovup<avxmodesuffixf2c>\t{%1, %0|%0, %1}"
[(set_attr "type" "ssemov")
+ (set_attr "movu" "1")
(set_attr "prefix" "vex")
(set_attr "mode" "<MODE>")])
@@ -367,6 +368,7 @@
&& !(MEM_P (operands[0]) && MEM_P (operands[1]))"
"movup<ssemodesuffixf2c>\t{%1, %0|%0, %1}"
[(set_attr "type" "ssemov")
+ (set_attr "movu" "1")
(set_attr "mode" "<MODE>")])
(define_insn "avx_movdqu<avxmodesuffix>"
@@ -377,6 +379,7 @@
"TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
"vmovdqu\t{%1, %0|%0, %1}"
[(set_attr "type" "ssemov")
+ (set_attr "movu" "1")
(set_attr "prefix" "vex")
(set_attr "mode" "<avxvecmode>")])
@@ -387,6 +390,7 @@
"TARGET_SSE2 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
"movdqu\t{%1, %0|%0, %1}"
[(set_attr "type" "ssemov")
+ (set_attr "movu" "1")
(set_attr "prefix_data16" "1")
(set_attr "mode" "TI")])
@@ -428,7 +432,7 @@
UNSPEC_MOVNT))]
"TARGET_SSE2"
"movntdq\t{%1, %0|%0, %1}"
- [(set_attr "type" "ssecvt")
+ [(set_attr "type" "ssemov")
(set_attr "prefix_data16" "1")
(set_attr "mode" "TI")])
@@ -438,7 +442,7 @@
UNSPEC_MOVNT))]
"TARGET_SSE2"
"movnti\t{%1, %0|%0, %1}"
- [(set_attr "type" "ssecvt")
+ [(set_attr "type" "ssemov")
(set_attr "mode" "V2DF")])
(define_insn "avx_lddqu<avxmodesuffix>"
@@ -449,6 +453,7 @@
"TARGET_AVX"
"vlddqu\t{%1, %0|%0, %1}"
[(set_attr "type" "ssecvt")
+ (set_attr "movu" "1")
(set_attr "prefix" "vex")
(set_attr "mode" "<avxvecmode>")])
@@ -458,7 +463,8 @@
UNSPEC_LDDQU))]
"TARGET_SSE3"
"lddqu\t{%1, %0|%0, %1}"
- [(set_attr "type" "ssecvt")
+ [(set_attr "type" "ssemov")
+ (set_attr "movu" "1")
(set_attr "prefix_rep" "1")
(set_attr "mode" "TI")])
@@ -765,6 +771,7 @@
"TARGET_SSE"
"%vrcpps\t{%1, %0|%0, %1}"
[(set_attr "type" "sse")
+ (set_attr "atom_sse_attr" "rcp")
(set_attr "prefix" "maybe_vex")
(set_attr "mode" "V4SF")])
@@ -791,6 +798,7 @@
"TARGET_SSE"
"rcpss\t{%1, %0|%0, %1}"
[(set_attr "type" "sse")
+ (set_attr "atom_sse_attr" "rcp")
(set_attr "mode" "SF")])
(define_expand "sqrtv8sf2"
@@ -836,6 +844,7 @@
"TARGET_SSE"
"%vsqrtps\t{%1, %0|%0, %1}"
[(set_attr "type" "sse")
+ (set_attr "atom_sse_attr" "sqrt")
(set_attr "prefix" "maybe_vex")
(set_attr "mode" "V4SF")])
@@ -880,6 +889,7 @@
"SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
"sqrts<ssemodesuffixf2c>\t{%1, %0|%0, %1}"
[(set_attr "type" "sse")
+ (set_attr "atom_sse_attr" "sqrt")
(set_attr "mode" "<ssescalarmode>")])
(define_expand "rsqrtv8sf2"
@@ -1043,7 +1053,7 @@
(const_int 1)))]
"SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
"<maxminfprefix>s<ssemodesuffixf2c>\t{%2, %0|%0, %2}"
- [(set_attr "type" "sse")
+ [(set_attr "type" "sseadd")
(set_attr "mode" "<ssescalarmode>")])
;; These versions of the min/max patterns implement exactly the operations
@@ -1179,6 +1189,7 @@
"TARGET_SSE3"
"addsubpd\t{%2, %0|%0, %2}"
[(set_attr "type" "sseadd")
+ (set_attr "atom_unit" "complex")
(set_attr "mode" "V2DF")])
(define_insn "avx_h<plusminus_insn>v4df3"
@@ -1302,6 +1313,7 @@
"TARGET_SSE3"
"h<plusminus_mnemonic>ps\t{%2, %0|%0, %2}"
[(set_attr "type" "sseadd")
+ (set_attr "atom_unit" "complex")
(set_attr "prefix_rep" "1")
(set_attr "mode" "V4SF")])
@@ -5069,6 +5081,7 @@
"TARGET_SSE2 && ix86_binary_operator_ok (MULT, V8HImode, operands)"
"pmaddwd\t{%2, %0|%0, %2}"
[(set_attr "type" "sseiadd")
+ (set_attr "atom_unit" "simul")
(set_attr "prefix_data16" "1")
(set_attr "mode" "TI")])
@@ -7018,7 +7031,7 @@
vpsrldq\t{$8, %1, %0|%0, %1, 8}
vmovq\t{%H1, %0|%0, %H1}
vmov{q}\t{%H1, %0|%0, %H1}"
- [(set_attr "type" "ssemov,sseishft,ssemov,imov")
+ [(set_attr "type" "ssemov,sseishft1,ssemov,imov")
(set_attr "memory" "*,none,*,*")
(set_attr "prefix" "vex")
(set_attr "mode" "V2SF,TI,TI,DI")])
@@ -7034,7 +7047,7 @@
psrldq\t{$8, %0|%0, 8}
movq\t{%H1, %0|%0, %H1}
mov{q}\t{%H1, %0|%0, %H1}"
- [(set_attr "type" "ssemov,sseishft,ssemov,imov")
+ [(set_attr "type" "ssemov,sseishft1,ssemov,imov")
(set_attr "memory" "*,none,*,*")
(set_attr "mode" "V2SF,TI,TI,DI")])
@@ -7050,7 +7063,7 @@
vmovhps\t{%1, %0|%0, %1}
vpsrldq\t{$8, %1, %0|%0, %1, 8}
vmovq\t{%H1, %0|%0, %H1}"
- [(set_attr "type" "ssemov,sseishft,ssemov")
+ [(set_attr "type" "ssemov,sseishft1,ssemov")
(set_attr "memory" "*,none,*")
(set_attr "prefix" "vex")
(set_attr "mode" "V2SF,TI,TI")])
@@ -7066,7 +7079,7 @@
movhps\t{%1, %0|%0, %1}
psrldq\t{$8, %0|%0, 8}
movq\t{%H1, %0|%0, %H1}"
- [(set_attr "type" "ssemov,sseishft,ssemov")
+ [(set_attr "type" "ssemov,sseishft1,ssemov")
(set_attr "memory" "*,none,*")
(set_attr "mode" "V2SF,TI,TI")])
@@ -7624,6 +7637,7 @@
"TARGET_SSE2"
"psadbw\t{%2, %0|%0, %2}"
[(set_attr "type" "sseiadd")
+ (set_attr "atom_unit" "simul")
(set_attr "prefix_data16" "1")
(set_attr "mode" "TI")])
@@ -7645,7 +7659,7 @@
UNSPEC_MOVMSK))]
"SSE_VEC_FLOAT_MODE_P (<MODE>mode)"
"%vmovmskp<ssemodesuffixf2c>\t{%1, %0|%0, %1}"
- [(set_attr "type" "ssecvt")
+ [(set_attr "type" "ssemov")
(set_attr "prefix" "maybe_vex")
(set_attr "mode" "<MODE>")])
@@ -7655,7 +7669,7 @@
UNSPEC_MOVMSK))]
"TARGET_SSE2"
"%vpmovmskb\t{%1, %0|%0, %1}"
- [(set_attr "type" "ssecvt")
+ [(set_attr "type" "ssemov")
(set_attr "prefix_data16" "1")
(set_attr "prefix" "maybe_vex")
(set_attr "mode" "SI")])
@@ -7678,7 +7692,7 @@
"TARGET_SSE2 && !TARGET_64BIT"
;; @@@ check ordering of operands in intel/nonintel syntax
"%vmaskmovdqu\t{%2, %1|%1, %2}"
- [(set_attr "type" "ssecvt")
+ [(set_attr "type" "ssemov")
(set_attr "prefix_data16" "1")
(set_attr "prefix" "maybe_vex")
(set_attr "mode" "TI")])
@@ -7692,7 +7706,7 @@
"TARGET_SSE2 && TARGET_64BIT"
;; @@@ check ordering of operands in intel/nonintel syntax
"%vmaskmovdqu\t{%2, %1|%1, %2}"
- [(set_attr "type" "ssecvt")
+ [(set_attr "type" "ssemov")
(set_attr "prefix_data16" "1")
(set_attr "prefix" "maybe_vex")
(set_attr "mode" "TI")])
@@ -7703,6 +7717,7 @@
"TARGET_SSE"
"%vldmxcsr\t%0"
[(set_attr "type" "sse")
+ (set_attr "atom_sse_attr" "mxcsr")
(set_attr "prefix" "maybe_vex")
(set_attr "memory" "load")])
@@ -7712,6 +7727,7 @@
"TARGET_SSE"
"%vstmxcsr\t%0"
[(set_attr "type" "sse")
+ (set_attr "atom_sse_attr" "mxcsr")
(set_attr "prefix" "maybe_vex")
(set_attr "memory" "store")])
@@ -7730,6 +7746,7 @@
"TARGET_SSE || TARGET_3DNOW_A"
"sfence"
[(set_attr "type" "sse")
+ (set_attr "atom_sse_attr" "fence")
(set_attr "memory" "unknown")])
(define_insn "sse2_clflush"
@@ -7738,6 +7755,7 @@
"TARGET_SSE2"
"clflush\t%a0"
[(set_attr "type" "sse")
+ (set_attr "atom_sse_attr" "fence")
(set_attr "memory" "unknown")])
(define_expand "sse2_mfence"
@@ -7755,6 +7773,7 @@
"TARGET_64BIT || TARGET_SSE2"
"mfence"
[(set_attr "type" "sse")
+ (set_attr "atom_sse_attr" "fence")
(set_attr "memory" "unknown")])
(define_expand "sse2_lfence"
@@ -7772,6 +7791,7 @@
"TARGET_SSE2"
"lfence"
[(set_attr "type" "sse")
+ (set_attr "atom_sse_attr" "lfence")
(set_attr "memory" "unknown")])
(define_insn "sse3_mwait"
@@ -7895,6 +7915,7 @@
"TARGET_SSSE3"
"phaddw\t{%2, %0|%0, %2}"
[(set_attr "type" "sseiadd")
+ (set_attr "atom_unit" "complex")
(set_attr "prefix_data16" "1")
(set_attr "prefix_extra" "1")
(set_attr "mode" "TI")])
@@ -7923,6 +7944,7 @@
"TARGET_SSSE3"
"phaddw\t{%2, %0|%0, %2}"
[(set_attr "type" "sseiadd")
+ (set_attr "atom_unit" "complex")
(set_attr "prefix_extra" "1")
(set_attr "mode" "DI")])
@@ -7977,6 +7999,7 @@
"TARGET_SSSE3"
"phaddd\t{%2, %0|%0, %2}"
[(set_attr "type" "sseiadd")
+ (set_attr "atom_unit" "complex")
(set_attr "prefix_data16" "1")
(set_attr "prefix_extra" "1")
(set_attr "mode" "TI")])
@@ -7997,6 +8020,7 @@
"TARGET_SSSE3"
"phaddd\t{%2, %0|%0, %2}"
[(set_attr "type" "sseiadd")
+ (set_attr "atom_unit" "complex")
(set_attr "prefix_extra" "1")
(set_attr "mode" "DI")])
@@ -8083,6 +8107,7 @@
"TARGET_SSSE3"
"phaddsw\t{%2, %0|%0, %2}"
[(set_attr "type" "sseiadd")
+ (set_attr "atom_unit" "complex")
(set_attr "prefix_data16" "1")
(set_attr "prefix_extra" "1")
(set_attr "mode" "TI")])
@@ -8111,6 +8136,7 @@
"TARGET_SSSE3"
"phaddsw\t{%2, %0|%0, %2}"
[(set_attr "type" "sseiadd")
+ (set_attr "atom_unit" "complex")
(set_attr "prefix_extra" "1")
(set_attr "mode" "DI")])
@@ -8197,6 +8223,7 @@
"TARGET_SSSE3"
"phsubw\t{%2, %0|%0, %2}"
[(set_attr "type" "sseiadd")
+ (set_attr "atom_unit" "complex")
(set_attr "prefix_data16" "1")
(set_attr "prefix_extra" "1")
(set_attr "mode" "TI")])
@@ -8225,6 +8252,7 @@
"TARGET_SSSE3"
"phsubw\t{%2, %0|%0, %2}"
[(set_attr "type" "sseiadd")
+ (set_attr "atom_unit" "complex")
(set_attr "prefix_extra" "1")
(set_attr "mode" "DI")])
@@ -8279,6 +8307,7 @@
"TARGET_SSSE3"
"phsubd\t{%2, %0|%0, %2}"
[(set_attr "type" "sseiadd")
+ (set_attr "atom_unit" "complex")
(set_attr "prefix_data16" "1")
(set_attr "prefix_extra" "1")
(set_attr "mode" "TI")])
@@ -8299,6 +8328,7 @@
"TARGET_SSSE3"
"phsubd\t{%2, %0|%0, %2}"
[(set_attr "type" "sseiadd")
+ (set_attr "atom_unit" "complex")
(set_attr "prefix_extra" "1")
(set_attr "mode" "DI")])
@@ -8385,6 +8415,7 @@
"TARGET_SSSE3"
"phsubsw\t{%2, %0|%0, %2}"
[(set_attr "type" "sseiadd")
+ (set_attr "atom_unit" "complex")
(set_attr "prefix_data16" "1")
(set_attr "prefix_extra" "1")
(set_attr "mode" "TI")])
@@ -8413,6 +8444,7 @@
"TARGET_SSSE3"
"phsubsw\t{%2, %0|%0, %2}"
[(set_attr "type" "sseiadd")
+ (set_attr "atom_unit" "complex")
(set_attr "prefix_extra" "1")
(set_attr "mode" "DI")])
@@ -8519,6 +8551,7 @@
"TARGET_SSSE3"
"pmaddubsw\t{%2, %0|%0, %2}"
[(set_attr "type" "sseiadd")
+ (set_attr "atom_unit" "simul")
(set_attr "prefix_data16" "1")
(set_attr "prefix_extra" "1")
(set_attr "mode" "TI")])
@@ -8557,6 +8590,7 @@
"TARGET_SSSE3"
"pmaddubsw\t{%2, %0|%0, %2}"
[(set_attr "type" "sseiadd")
+ (set_attr "atom_unit" "simul")
(set_attr "prefix_extra" "1")
(set_attr "mode" "DI")])
@@ -8764,6 +8798,7 @@
return "palignr\t{%3, %2, %0|%0, %2, %3}";
}
[(set_attr "type" "sseishft")
+ (set_attr "atom_unit" "sishuf")
(set_attr "prefix_data16" "1")
(set_attr "prefix_extra" "1")
(set_attr "mode" "TI")])
@@ -8780,6 +8815,7 @@
return "palignr\t{%3, %2, %0|%0, %2, %3}";
}
[(set_attr "type" "sseishft")
+ (set_attr "atom_unit" "sishuf")
(set_attr "prefix_extra" "1")
(set_attr "mode" "DI")])
@@ -8966,7 +9002,7 @@
UNSPEC_MOVNTDQA))]
"TARGET_SSE4_1"
"%vmovntdqa\t{%1, %0|%0, %1}"
- [(set_attr "type" "ssecvt")
+ [(set_attr "type" "ssemov")
(set_attr "prefix_extra" "1")
(set_attr "prefix" "maybe_vex")
(set_attr "mode" "TI")])
diff --git a/gcc-4.4.3/gcc/config/i386/ssemath.h b/gcc-4.4.3/gcc/config/i386/ssemath.h
new file mode 100644
index 000000000..357d6a378
--- /dev/null
+++ b/gcc-4.4.3/gcc/config/i386/ssemath.h
@@ -0,0 +1,25 @@
+/* Copyright (C) 2010
+ 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/>. */
+
+#undef TARGET_FPMATH_DEFAULT
+#define TARGET_FPMATH_DEFAULT (TARGET_SSE2 ? FPMATH_SSE : FPMATH_387)
+
+#undef TARGET_SUBTARGET32_ISA_DEFAULT
+#define TARGET_SUBTARGET32_ISA_DEFAULT \
+ (OPTION_MASK_ISA_MMX | OPTION_MASK_ISA_SSE | OPTION_MASK_ISA_SSE2)
diff --git a/gcc-4.4.3/gcc/config/i386/x86intrin.h b/gcc-4.4.3/gcc/config/i386/x86intrin.h
index d848811d3..fead76635 100644
--- a/gcc-4.4.3/gcc/config/i386/x86intrin.h
+++ b/gcc-4.4.3/gcc/config/i386/x86intrin.h
@@ -56,6 +56,10 @@
#include <bmmintrin.h>
#endif
+#ifdef __LWP__
+#include <lwpintrin.h>
+#endif
+
#if defined (__AES__) || defined (__PCLMUL__)
#include <wmmintrin.h>
#endif
diff --git a/gcc-4.4.3/gcc/config/linux-android.h b/gcc-4.4.3/gcc/config/linux-android.h
index a43bab5b0..5ca3858a2 100644
--- a/gcc-4.4.3/gcc/config/linux-android.h
+++ b/gcc-4.4.3/gcc/config/linux-android.h
@@ -20,6 +20,12 @@
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
+#define ANDROID_TARGET_OS_CPP_BUILTINS() \
+ do { \
+ if (OPTION_ANDROID) \
+ builtin_define ("__ANDROID__"); \
+ } while (0)
+
#if ANDROID_DEFAULT
# define NOANDROID "mno-android"
#else
diff --git a/gcc-4.4.3/gcc/config/linux.h b/gcc-4.4.3/gcc/config/linux.h
index 443db22bd..740ddb7be 100644
--- a/gcc-4.4.3/gcc/config/linux.h
+++ b/gcc-4.4.3/gcc/config/linux.h
@@ -42,7 +42,11 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
provides part of the support for getting C++ file-scope static
object constructed before entering `main'. */
-#if defined HAVE_LD_PIE
+#if defined (HAVE_LD_PIE) && defined (ENABLE_CRTBEGINTS)
+#define LINUX_TARGET_STARTFILE_SPEC \
+ "%{!shared: %{pg|p|profile:gcrt1.o%s;pie:Scrt1.o%s;:crt1.o%s}} crti.o%s \
+ %{static:%{pie:crtbeginTS.o%s;:crtbeginT.o%s}} %{!static:%{shared|pie:crtbeginS.o%s;:crtbegin.o%s}}"
+#elif defined (HAVE_LD_PIE) && ! defined (ENABLE_CRTBEGINTS)
#define LINUX_TARGET_STARTFILE_SPEC \
"%{!shared: %{pg|p|profile:gcrt1.o%s;pie:Scrt1.o%s;:crt1.o%s}} \
crti.o%s %{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbegin.o%s}"
@@ -96,8 +100,6 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
builtin_assert ("system=linux"); \
builtin_assert ("system=unix"); \
builtin_assert ("system=posix"); \
- if (OPTION_ANDROID) \
- builtin_define ("__ANDROID__"); \
} while (0)
#if defined(HAVE_LD_EH_FRAME_HDR)
diff --git a/gcc-4.4.3/gcc/config/mips/linux64.h b/gcc-4.4.3/gcc/config/mips/linux64.h
index 2f24dfa14..505d8b1d4 100644
--- a/gcc-4.4.3/gcc/config/mips/linux64.h
+++ b/gcc-4.4.3/gcc/config/mips/linux64.h
@@ -39,8 +39,10 @@ along with GCC; see the file COPYING3. If not see
#define GLIBC_DYNAMIC_LINKER64 "/lib64/ld.so.1"
#define GLIBC_DYNAMIC_LINKERN32 "/lib32/ld.so.1"
#define UCLIBC_DYNAMIC_LINKERN32 "/lib32/ld-uClibc.so.0"
+#define BIONIC_DYNAMIC_LINKERN32 "/system/bin/linker32"
#define LINUX_DYNAMIC_LINKERN32 \
- CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKERN32, UCLIBC_DYNAMIC_LINKERN32)
+ CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKERN32, UCLIBC_DYNAMIC_LINKERN32, \
+ BIONIC_DYNAMIC_LINKERN32)
#undef LINK_SPEC
#define LINK_SPEC "\
diff --git a/gcc-4.4.3/gcc/config/rs6000/linux64.h b/gcc-4.4.3/gcc/config/rs6000/linux64.h
index 3ccbe21c8..7ecf98742 100644
--- a/gcc-4.4.3/gcc/config/rs6000/linux64.h
+++ b/gcc-4.4.3/gcc/config/rs6000/linux64.h
@@ -156,7 +156,7 @@ extern int dot_symbols;
#endif
#define ASM_SPEC32 "-a32 %{n} %{T} %{Ym,*} %{Yd,*} \
-%{mrelocatable} %{mrelocatable-lib} %{fpic:-K PIC} %{fPIC:-K PIC} \
+%{mrelocatable} %{mrelocatable-lib} %{fpic|fPIC|fpie|fPIE:-K PIC} \
%{memb} %{!memb: %{msdata: -memb} %{msdata=eabi: -memb}} \
%{!mlittle: %{!mlittle-endian: %{!mbig: %{!mbig-endian: \
%{mcall-freebsd: -mbig} \
diff --git a/gcc-4.4.3/gcc/config/rs6000/sysv4.h b/gcc-4.4.3/gcc/config/rs6000/sysv4.h
index 339d51847..d9407e97d 100644
--- a/gcc-4.4.3/gcc/config/rs6000/sysv4.h
+++ b/gcc-4.4.3/gcc/config/rs6000/sysv4.h
@@ -883,7 +883,12 @@ SVR4_ASM_SPEC \
%{!mnewlib: %{pthread:-lpthread} %{shared:-lc} \
%{!shared: %{profile:-lc_p} %{!profile:-lc}}}"
-#ifdef HAVE_LD_PIE
+#if defined (HAVE_LD_PIE) && defined (ENABLE_CRTBEGINTS)
+#define STARTFILE_LINUX_SPEC "\
+%{!shared: %{pg|p|profile:gcrt1.o%s;pie:Scrt1.o%s;:crt1.o%s}} \
+%{mnewlib:ecrti.o%s;:crti.o%s} \
+%{static:%{pie:crtbeginTS.o%s;:crtbeginT.o%s}} %{!static:%{shared|pie:crtbeginS.o%s;:crtbegin.o%s}}"
+#elif defined (HAVE_LD_PIE) && ! defined (ENABLE_CRTBEGINTS)
#define STARTFILE_LINUX_SPEC "\
%{!shared: %{pg|p|profile:gcrt1.o%s;pie:Scrt1.o%s;:crt1.o%s}} \
%{mnewlib:ecrti.o%s;:crti.o%s} \
diff --git a/gcc-4.4.3/gcc/config/sparc/sparc.c b/gcc-4.4.3/gcc/config/sparc/sparc.c
index d007ce551..b7d94f545 100644
--- a/gcc-4.4.3/gcc/config/sparc/sparc.c
+++ b/gcc-4.4.3/gcc/config/sparc/sparc.c
@@ -6104,7 +6104,7 @@ enum rtx_code
sparc_emit_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison)
{
const char *qpfunc;
- rtx slot0, slot1, result, tem, tem2;
+ rtx slot0, slot1, result, tem, tem2, libfunc;
enum machine_mode mode;
enum rtx_code new_comparison;
@@ -6167,7 +6167,8 @@ sparc_emit_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison)
emit_move_insn (slot1, y);
}
- emit_library_call (gen_rtx_SYMBOL_REF (Pmode, qpfunc), LCT_NORMAL,
+ libfunc = gen_rtx_SYMBOL_REF (Pmode, qpfunc);
+ emit_library_call (libfunc, LCT_NORMAL,
DImode, 2,
XEXP (slot0, 0), Pmode,
XEXP (slot1, 0), Pmode);
@@ -6175,7 +6176,8 @@ sparc_emit_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison)
}
else
{
- emit_library_call (gen_rtx_SYMBOL_REF (Pmode, qpfunc), LCT_NORMAL,
+ libfunc = gen_rtx_SYMBOL_REF (Pmode, qpfunc);
+ emit_library_call (libfunc, LCT_NORMAL,
SImode, 2,
x, TFmode, y, TFmode);
mode = SImode;
@@ -6186,7 +6188,7 @@ sparc_emit_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison)
register so reload doesn't clobber the value if it needs
the return register for a spill reg. */
result = gen_reg_rtx (mode);
- emit_move_insn (result, hard_libcall_value (mode));
+ emit_move_insn (result, hard_libcall_value (mode, libfunc));
switch (comparison)
{
diff --git a/gcc-4.4.3/gcc/configure b/gcc-4.4.3/gcc/configure
index 47a400135..51db4d2b8 100755
--- a/gcc-4.4.3/gcc/configure
+++ b/gcc-4.4.3/gcc/configure
@@ -458,7 +458,7 @@ ac_includes_default="\
# include <unistd.h>
#endif"
-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os target_noncanonical build_libsubdir build_subdir host_subdir target_subdir GENINSRC CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT GNATBIND ac_ct_GNATBIND GNATMAKE ac_ct_GNATMAKE NO_MINUS_C_MINUS_O OUTPUT_OPTION CPP EGREP loose_warn strict_warn warn_cflags nocommon_flag TREEBROWSER valgrind_path valgrind_path_defines valgrind_command coverage_flags enable_multilib enable_decimal_float enable_fixed_point enable_shared NATIVE_SYSTEM_HEADER_DIR RUNTIME_ROOT_PREFIX_DEFINE SYSROOT_CFLAGS_FOR_TARGET TARGET_SYSTEM_ROOT TARGET_SYSTEM_ROOT_DEFINE CROSS_SYSTEM_HEADER_DIR onestep PKGVERSION REPORT_BUGS_TO REPORT_BUGS_TEXI datarootdir docdir htmldir SET_MAKE AWK LN_S LN RANLIB ac_ct_RANLIB ranlib_flags INSTALL INSTALL_PROGRAM INSTALL_DATA make_compare_target have_mktemp_command MAKEINFO BUILD_INFO GENERATED_MANPAGES FLEX BISON NM AR COLLECT2_LIBS GNAT_LIBEXC LDEXP_LIB TARGET_GETGROUPS_T LIBICONV LTLIBICONV LIBICONV_DEP manext objext gthread_flags extra_modes_file extra_opt_files USE_NLS LIBINTL LIBINTL_DEP INCINTL XGETTEXT GMSGFMT POSUB CATALOGS DATADIRNAME INSTOBJEXT GENCAT CATOBJEXT CROSS ALL SYSTEM_HEADER_DIR inhibit_libc CC_FOR_BUILD BUILD_CFLAGS BUILD_LDFLAGS STMP_FIXINC STMP_FIXPROTO collect2 LIBTOOL SED FGREP GREP LD DUMPBIN ac_ct_DUMPBIN OBJDUMP ac_ct_OBJDUMP ac_ct_AR STRIP ac_ct_STRIP lt_ECHO DSYMUTIL ac_ct_DSYMUTIL NMEDIT ac_ct_NMEDIT LIPO ac_ct_LIPO OTOOL ac_ct_OTOOL OTOOL64 ac_ct_OTOOL64 objdir enable_fast_install gcc_cv_as ORIGINAL_AS_FOR_TARGET gcc_cv_ld ORIGINAL_LD_FOR_TARGET ORIGINAL_GOLD_FOR_TARGET gcc_cv_nm ORIGINAL_NM_FOR_TARGET gcc_cv_objdump gcc_cv_readelf libgcc_visibility GGC zlibdir zlibinc MAINT gcc_tooldir dollar slibdir subdirs srcdir all_compilers all_gtfiles all_lang_makefrags all_lang_makefiles all_languages all_selected_languages build_exeext build_install_headers_dir build_xm_file_list build_xm_include_list build_xm_defines build_file_translate check_languages cpp_install_dir xmake_file tmake_file extra_gcc_objs extra_headers_list extra_objs extra_parts extra_passes extra_programs float_h_file gcc_config_arguments gcc_gxx_include_dir host_exeext host_xm_file_list host_xm_include_list host_xm_defines out_host_hook_obj install lang_opt_files lang_specs_files lang_tree_files local_prefix md_file objc_boehm_gc out_file out_object_file thread_file tm_file_list tm_include_list tm_defines tm_p_file_list tm_p_include_list xm_file_list xm_include_list xm_defines c_target_objs cxx_target_objs fortran_target_objs target_cpu_default GMPLIBS GMPINC PPLLIBS PPLINC CLOOGLIBS CLOOGINC pluginlibs enable_plugin LIBOBJS LTLIBOBJS'
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os target_noncanonical build_libsubdir build_subdir host_subdir target_subdir GENINSRC CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT GNATBIND ac_ct_GNATBIND GNATMAKE ac_ct_GNATMAKE NO_MINUS_C_MINUS_O OUTPUT_OPTION CPP EGREP loose_warn strict_warn warn_cflags nocommon_flag TREEBROWSER valgrind_path valgrind_path_defines valgrind_command coverage_flags enable_multilib enable_decimal_float enable_fixed_point enable_shared NATIVE_SYSTEM_HEADER_DIR RUNTIME_ROOT_PREFIX_DEFINE SYSROOT_CFLAGS_FOR_TARGET TARGET_SYSTEM_ROOT TARGET_SYSTEM_ROOT_DEFINE CROSS_SYSTEM_HEADER_DIR onestep PKGVERSION REPORT_BUGS_TO REPORT_BUGS_TEXI datarootdir docdir htmldir SET_MAKE AWK LN_S LN RANLIB ac_ct_RANLIB ranlib_flags INSTALL INSTALL_PROGRAM INSTALL_DATA make_compare_target have_mktemp_command MAKEINFO BUILD_INFO GENERATED_MANPAGES FLEX BISON NM AR COLLECT2_LIBS GNAT_LIBEXC LDEXP_LIB TARGET_GETGROUPS_T LIBICONV LTLIBICONV LIBICONV_DEP manext objext gthread_flags extra_modes_file extra_opt_files USE_NLS LIBINTL LIBINTL_DEP INCINTL XGETTEXT GMSGFMT POSUB CATALOGS DATADIRNAME INSTOBJEXT GENCAT CATOBJEXT CROSS ALL SYSTEM_HEADER_DIR inhibit_libc CC_FOR_BUILD BUILD_CFLAGS BUILD_LDFLAGS STMP_FIXINC STMP_FIXPROTO collect2 LIBTOOL SED FGREP GREP LD DUMPBIN ac_ct_DUMPBIN OBJDUMP ac_ct_OBJDUMP ac_ct_AR STRIP ac_ct_STRIP lt_ECHO DSYMUTIL ac_ct_DSYMUTIL NMEDIT ac_ct_NMEDIT LIPO ac_ct_LIPO OTOOL ac_ct_OTOOL OTOOL64 ac_ct_OTOOL64 objdir enable_fast_install gcc_cv_as ORIGINAL_AS_FOR_TARGET gcc_cv_ld ORIGINAL_LD_FOR_TARGET ORIGINAL_GOLD_FOR_TARGET gcc_cv_nm ORIGINAL_NM_FOR_TARGET gcc_cv_objdump gcc_cv_readelf libgcc_visibility enable_esp enable_crtbeginTS GGC zlibdir zlibinc MAINT gcc_tooldir dollar slibdir link_rpath_spec subdirs srcdir all_compilers all_gtfiles all_lang_makefrags all_lang_makefiles all_languages all_selected_languages build_exeext build_install_headers_dir build_xm_file_list build_xm_include_list build_xm_defines build_file_translate check_languages cpp_install_dir xmake_file tmake_file extra_gcc_objs extra_headers_list extra_objs extra_parts extra_passes extra_programs float_h_file gcc_config_arguments gcc_gxx_include_dir host_exeext host_xm_file_list host_xm_include_list host_xm_defines out_host_hook_obj install lang_opt_files lang_specs_files lang_tree_files local_prefix md_file objc_boehm_gc out_file out_object_file thread_file tm_file_list tm_include_list tm_defines tm_p_file_list tm_p_include_list xm_file_list xm_include_list xm_defines c_target_objs cxx_target_objs fortran_target_objs target_cpu_default GMPLIBS GMPINC PPLLIBS PPLINC CLOOGLIBS CLOOGINC pluginlibs enable_plugin LIBOBJS LTLIBOBJS'
ac_subst_files='language_hooks'
ac_pwd=`pwd`
@@ -1132,6 +1132,7 @@ Optional Packages:
--with-datarootdir=DIR Use DIR as the data root [PREFIX/share]
--with-docdir=DIR Install documentation in DIR [DATAROOTDIR]
--with-htmldir=DIR html documentation in in DIR [DOCDIR]
+ --with-rpath-spec=SPEC Use rpath spec as part of default link specs
Some influential environment variables:
CC C compiler command
@@ -14594,13 +14595,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:14597: $ac_compile\"" >&5)
+ (eval echo "\"\$as_me:14598: $ac_compile\"" >&5)
(eval "$ac_compile" 2>conftest.err)
cat conftest.err >&5
- (eval echo "\"\$as_me:14600: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+ (eval echo "\"\$as_me:14601: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
(eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
cat conftest.err >&5
- (eval echo "\"\$as_me:14603: output\"" >&5)
+ (eval echo "\"\$as_me:14604: output\"" >&5)
cat conftest.out >&5
if $GREP 'External.*some_variable' conftest.out > /dev/null; then
lt_cv_nm_interface="MS dumpbin"
@@ -15757,7 +15758,7 @@ ia64-*-hpux*)
;;
*-*-irix6*)
# Find out which ABI we are using.
- echo '#line 15760 "configure"' > conftest.$ac_ext
+ echo '#line 15761 "configure"' > conftest.$ac_ext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
@@ -17071,11 +17072,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:17074: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:17075: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:17078: \$? = $ac_status" >&5
+ echo "$as_me:17079: \$? = $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.
@@ -17410,11 +17411,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:17413: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:17414: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:17417: \$? = $ac_status" >&5
+ echo "$as_me:17418: \$? = $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.
@@ -17515,11 +17516,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:17518: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:17519: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:17522: \$? = $ac_status" >&5
+ echo "$as_me:17523: \$? = $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
@@ -17570,11 +17571,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:17573: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:17574: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:17577: \$? = $ac_status" >&5
+ echo "$as_me:17578: \$? = $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
@@ -20382,7 +20383,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 20385 "configure"
+#line 20386 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -20478,7 +20479,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 20481 "configure"
+#line 20482 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -24438,6 +24439,50 @@ echo "$as_me: WARNING: --build-id is not supported by your linker; --enable-link
fi
fi
+echo "$as_me:$LINENO: checking linker -z now support" >&5
+echo $ECHO_N "checking linker -z now support... $ECHO_C" >&6
+if test "${gcc_cv_ld_now+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ gcc_cv_ld_now=no
+if test $in_tree_ld = yes ; then
+ if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 16 -o "$gcc_cv_gld_major_version" -gt 2 \
+ && test $in_tree_ld_is_elf = yes; then
+ gcc_cv_ld_now=yes
+ fi
+elif test x$gcc_cv_ld != x; then
+ # Check if linker supports -z now options
+ if $gcc_cv_ld --help 2>/dev/null | grep now > /dev/null; then
+ gcc_cv_ld_now=yes
+ fi
+fi
+
+fi
+echo "$as_me:$LINENO: result: $gcc_cv_ld_now" >&5
+echo "${ECHO_T}$gcc_cv_ld_now" >&6
+
+echo "$as_me:$LINENO: checking linker -z relro support" >&5
+echo $ECHO_N "checking linker -z relro support... $ECHO_C" >&6
+if test "${gcc_cv_ld_relro+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ gcc_cv_ld_relro=no
+if test $in_tree_ld = yes ; then
+ if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 16 -o "$gcc_cv_gld_major_version" -gt 2 \
+ && test $in_tree_ld_is_elf = yes; then
+ gcc_cv_ld_relro=yes
+ fi
+elif test x$gcc_cv_ld != x; then
+ # Check if linker supports -z relro and -z norelro options
+ if $gcc_cv_ld --help 2>/dev/null | grep relro > /dev/null; then
+ gcc_cv_ld_relro=yes
+ fi
+fi
+
+fi
+echo "$as_me:$LINENO: result: $gcc_cv_ld_relro" >&5
+echo "${ECHO_T}$gcc_cv_ld_relro" >&6
+
echo "$as_me:$LINENO: checking linker --sysroot support" >&5
echo $ECHO_N "checking linker --sysroot support... $ECHO_C" >&6
if test "${gcc_cv_ld_sysroot+set}" = set; then
@@ -24636,6 +24681,40 @@ _ACEOF
fi
+if test x$enable_esp = xyes ; then
+ if test x$gcc_cv_ld_relro = xyes && test x$gcc_cv_ld_now = xyes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define ENABLE_ESP 1
+_ACEOF
+
+ else
+ { { echo "$as_me:$LINENO: error: *** --enable-esp Need a linker that support -z now and -z relro." >&5
+echo "$as_me: error: *** --enable-esp Need a linker that support -z now and -z relro." >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+fi
+
+
+if test x$enable_esp = xyes ; then
+ case "$target" in
+ *-*-linux*)
+ if test x$gcc_cv_ld_pie = xyes && test x$lt_cv_prog_compiler_static_works = xyes; then
+ enable_crtbeginTS=yes
+ fi
+ ;;
+ *) enable_crtbeginTS=no ;;
+ esac
+fi
+
+if test x$enable_crtbeginTS = xyes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define ENABLE_CRTBEGINTS 1
+_ACEOF
+
+fi
+
# Check if TFmode long double should be used by default or not.
# Some glibc targets used DFmode long double, but with glibc 2.4
# and later they can use TFmode.
@@ -24972,6 +25051,17 @@ else
fi;
+# Google-local http://b/2739909
+
+# Check whether --with-rpath-spec or --without-rpath-spec was given.
+if test "${with_rpath_spec+set}" = set; then
+ withval="$with_rpath_spec"
+ link_rpath_spec="$withval"
+else
+ link_rpath_spec=
+fi;
+
+
# Substitute configuration variables
@@ -26060,6 +26150,8 @@ s,@ORIGINAL_NM_FOR_TARGET@,$ORIGINAL_NM_FOR_TARGET,;t t
s,@gcc_cv_objdump@,$gcc_cv_objdump,;t t
s,@gcc_cv_readelf@,$gcc_cv_readelf,;t t
s,@libgcc_visibility@,$libgcc_visibility,;t t
+s,@enable_esp@,$enable_esp,;t t
+s,@enable_crtbeginTS@,$enable_crtbeginTS,;t t
s,@GGC@,$GGC,;t t
s,@zlibdir@,$zlibdir,;t t
s,@zlibinc@,$zlibinc,;t t
@@ -26067,6 +26159,7 @@ s,@MAINT@,$MAINT,;t t
s,@gcc_tooldir@,$gcc_tooldir,;t t
s,@dollar@,$dollar,;t t
s,@slibdir@,$slibdir,;t t
+s,@link_rpath_spec@,$link_rpath_spec,;t t
s,@subdirs@,$subdirs,;t t
s,@srcdir@,$srcdir,;t t
s,@all_compilers@,$all_compilers,;t t
diff --git a/gcc-4.4.3/gcc/configure.ac b/gcc-4.4.3/gcc/configure.ac
index 1b8fcf614..1ee190a76 100644
--- a/gcc-4.4.3/gcc/configure.ac
+++ b/gcc-4.4.3/gcc/configure.ac
@@ -3651,6 +3651,38 @@ if test x"$enable_linker_build_id" = xyes; then
fi
fi
+AC_CACHE_CHECK(linker -z now support,
+gcc_cv_ld_now,
+[gcc_cv_ld_now=no
+if test $in_tree_ld = yes ; then
+ if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 16 -o "$gcc_cv_gld_major_version" -gt 2 \
+ && test $in_tree_ld_is_elf = yes; then
+ gcc_cv_ld_now=yes
+ fi
+elif test x$gcc_cv_ld != x; then
+ # Check if linker supports -z now options
+ if $gcc_cv_ld --help 2>/dev/null | grep now > /dev/null; then
+ gcc_cv_ld_now=yes
+ fi
+fi
+])
+
+AC_CACHE_CHECK(linker -z relro support,
+gcc_cv_ld_relro,
+[gcc_cv_ld_relro=no
+if test $in_tree_ld = yes ; then
+ if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 16 -o "$gcc_cv_gld_major_version" -gt 2 \
+ && test $in_tree_ld_is_elf = yes; then
+ gcc_cv_ld_relro=yes
+ fi
+elif test x$gcc_cv_ld != x; then
+ # Check if linker supports -z relro and -z norelro options
+ if $gcc_cv_ld --help 2>/dev/null | grep relro > /dev/null; then
+ gcc_cv_ld_relro=yes
+ fi
+fi
+])
+
AC_CACHE_CHECK(linker --sysroot support,
gcc_cv_ld_sysroot,
[gcc_cv_ld_sysroot=no
@@ -3734,6 +3766,32 @@ if test x$gcc_cv_libc_provides_ssp = xyes; then
[Define if your target C library provides stack protector support])
fi
+if test x$enable_esp = xyes ; then
+ if test x$gcc_cv_ld_relro = xyes && test x$gcc_cv_ld_now = xyes; then
+ AC_DEFINE(ENABLE_ESP, 1,
+ [Define if your target support esp and you have enable it.])
+ else
+ AC_MSG_ERROR([*** --enable-esp Need a linker that support -z now and -z relro.])
+ fi
+fi
+AC_SUBST([enable_esp])
+
+if test x$enable_esp = xyes ; then
+ case "$target" in
+ *-*-linux*)
+ if test x$gcc_cv_ld_pie = xyes && test x$lt_cv_prog_compiler_static_works = xyes; then
+ enable_crtbeginTS=yes
+ fi
+ ;;
+ *) enable_crtbeginTS=no ;;
+ esac
+fi
+AC_SUBST([enable_crtbeginTS])
+if test x$enable_crtbeginTS = xyes; then
+ AC_DEFINE(ENABLE_CRTBEGINTS, 1,
+ [Define if your target crtbeginTS support])
+fi
+
# Check if TFmode long double should be used by default or not.
# Some glibc targets used DFmode long double, but with glibc 2.4
# and later they can use TFmode.
@@ -4038,6 +4096,13 @@ htmldir="\${prefix}/$with_htmldir",
htmldir='$(docdir)')
AC_SUBST(htmldir)
+# Google-local http://b/2739909
+AC_ARG_WITH([rpath-spec],
+[ --with-rpath-spec=SPEC Use rpath spec as part of default link specs],
+[link_rpath_spec="$withval"],
+[link_rpath_spec=])
+AC_SUBST(link_rpath_spec)
+
# Substitute configuration variables
AC_SUBST(subdirs)
AC_SUBST(srcdir)
diff --git a/gcc-4.4.3/gcc/coverage.c b/gcc-4.4.3/gcc/coverage.c
index de9c0e401..19466d35a 100644
--- a/gcc-4.4.3/gcc/coverage.c
+++ b/gcc-4.4.3/gcc/coverage.c
@@ -119,6 +119,9 @@ static char *da_file_name;
static char *da_base_file_name;
static char *main_input_file_name;
+/* Filename for the global pmu profile */
+static char pmu_profile_filename[] = "pmuprofile";
+
/* Hash table of count data. */
static htab_t counts_hash = NULL;
@@ -149,6 +152,16 @@ static unsigned num_cpp_includes = 0;
/* True if the current module has any asm statements. */
static bool has_asm_statement;
+/* extern const char * __gcov_pmu_profile_filename */
+static tree gcov_pmu_filename_decl = NULL_TREE;
+/* extern const char * __gcov_pmu_profile_options */
+static tree gcov_pmu_options_decl = NULL_TREE;
+/* extern gcov_unsigned_t __gcov_pmu_top_n_address */
+static tree gcov_pmu_top_n_address_decl = NULL_TREE;
+
+/* To ensure that the above variables are initialized only once. */
+static int pmu_profiling_initialized = 0;
+
/* Forward declarations. */
static hashval_t htab_counts_entry_hash (const void *);
static int htab_counts_entry_eq (const void *, const void *);
@@ -160,8 +173,10 @@ static tree build_ctr_info_type (void);
static tree build_ctr_info_value (unsigned, tree);
static tree build_gcov_info (void);
static void create_coverage (void);
-static char * get_da_file_name (const char *);
static char * xstrdup_mask_random (const char *);
+static void init_pmu_profiling (void);
+static bool profiling_enabled_p (void);
+
/* Return the type node for gcov_type. */
@@ -171,6 +186,15 @@ get_gcov_type (void)
return lang_hooks.types.type_for_size (GCOV_TYPE_SIZE, false);
}
+/* Return the type node for gcov_float_t. */
+
+tree
+get_gcov_float_t (void)
+{
+ return double_type_node;
+}
+
+
/* Return the type node for gcov_unsigned_t. */
tree
@@ -745,16 +769,24 @@ get_coverage_counts_no_warn (struct function *f, unsigned counter,
{
counts_entry_t *entry, elt;
- gcc_assert (flag_dyn_ipa);
+ gcc_assert (flag_dyn_ipa || flag_optimize_locality);
/* No hash table, no counts. */
if (!counts_hash || !f)
return NULL;
elt.ident = FUNC_DECL_GLOBAL_ID (f);
- elt.name = NULL;
+
+ if (flag_dyn_ipa)
+ elt.name = NULL;
+ else
+ elt.name = xstrdup_mask_random (IDENTIFIER_POINTER (
+ DECL_ASSEMBLER_NAME (current_function_decl)));
+
elt.ctr = counter;
entry = (counts_entry_t *) htab_find (counts_hash, &elt);
+ if (elt.name)
+ free (elt.name);
if (!entry)
return NULL;
@@ -1779,7 +1811,7 @@ create_coverage (void)
no_coverage = 1; /* Disable any further coverage. */
- if (!prg_ctr_mask)
+ if (!prg_ctr_mask && !flag_pmu_profile_generate)
return;
t = build_gcov_info ();
@@ -1813,7 +1845,7 @@ create_coverage (void)
/* Get the da file name, given base file name. */
-static char *
+char *
get_da_file_name (const char *base_file_name)
{
char *da_file_name;
@@ -1999,6 +2031,117 @@ coverage_init (const char *filename, const char* source_name)
read_counts_file (get_da_file_name (module_infos[i]->da_filename),
module_infos[i]->ident);
}
+
+ /* Define variables which are referenced at runtime by libgcov. */
+ if (profiling_enabled_p ())
+ {
+ init_pmu_profiling ();
+ tree_init_instrumentation_sampling ();
+ }
+}
+
+/* Return True if any type of profiling is enabled which requires linking
+ in libgcov otherwise return False. */
+
+static bool
+profiling_enabled_p (void)
+{
+ return flag_pmu_profile_generate || profile_arc_flag ||
+ flag_profile_generate_sampling || flag_test_coverage ||
+ flag_branch_probabilities || flag_profile_reusedist;
+}
+
+/* Construct variables for PMU profiling.
+ 1) __gcov_pmu_profile_filename,
+ 2) __gcov_pmu_profile_options,
+ 3) __gcov_pmu_top_n_address. */
+
+static void
+init_pmu_profiling (void)
+{
+ if (!pmu_profiling_initialized)
+ {
+ unsigned top_n_addr = PARAM_VALUE (PARAM_PMU_PROFILE_N_ADDRESS);
+ tree filename_ptr, options_ptr;
+
+ /* Construct an initializer for __gcov_pmu_profile_filename. */
+ gcov_pmu_filename_decl =
+ build_decl (VAR_DECL,
+ get_identifier ("__gcov_pmu_profile_filename"),
+ get_const_string_type ());
+ TREE_PUBLIC (gcov_pmu_filename_decl) = 1;
+ DECL_ARTIFICIAL (gcov_pmu_filename_decl) = 1;
+ DECL_ONE_ONLY (gcov_pmu_filename_decl) = 1;
+ TREE_STATIC (gcov_pmu_filename_decl) = 1;
+
+ if (flag_pmu_profile_generate)
+ {
+ const char *filename = get_da_file_name (pmu_profile_filename);
+ int file_name_len;
+ tree filename_string;
+ file_name_len = strlen (filename);
+ filename_string = build_string (file_name_len + 1, filename);
+ TREE_TYPE (filename_string) = build_array_type
+ (char_type_node, build_index_type
+ (build_int_cst (NULL_TREE, file_name_len)));
+ filename_ptr = build1 (ADDR_EXPR, get_const_string_type (),
+ filename_string);
+ }
+ else
+ filename_ptr = null_pointer_node;
+
+ DECL_INITIAL (gcov_pmu_filename_decl) = filename_ptr;
+ assemble_variable (gcov_pmu_filename_decl, 0, 0, 0);
+
+ /* Construct an initializer for __gcov_pmu_profile_options. */
+ gcov_pmu_options_decl =
+ build_decl (VAR_DECL,
+ get_identifier ("__gcov_pmu_profile_options"),
+ get_const_string_type ());
+ TREE_PUBLIC (gcov_pmu_options_decl) = 1;
+ DECL_ARTIFICIAL (gcov_pmu_options_decl) = 1;
+ DECL_ONE_ONLY (gcov_pmu_options_decl) = 1;
+ TREE_STATIC (gcov_pmu_options_decl) = 1;
+
+ /* If the flag is false we generate a null pointer to indicate
+ that we are not doing the pmu profiling. */
+ if (flag_pmu_profile_generate)
+ {
+ const char *pmu_options = flag_pmu_profile_generate;
+ int pmu_options_len;
+ tree pmu_options_string;
+
+ pmu_options_len = strlen (pmu_options);
+ pmu_options_string = build_string (pmu_options_len + 1, pmu_options);
+ TREE_TYPE (pmu_options_string) = build_array_type
+ (char_type_node, build_index_type
+ (build_int_cst (NULL_TREE, pmu_options_len)));
+ options_ptr = build1 (ADDR_EXPR, get_const_string_type (),
+ pmu_options_string);
+ }
+ else
+ options_ptr = null_pointer_node;
+
+ DECL_INITIAL (gcov_pmu_options_decl) = options_ptr;
+ assemble_variable (gcov_pmu_options_decl, 0, 0, 0);
+
+ /* Construct an initializer for __gcov_pmu_top_n_address. We
+ don't need to guard this with the flag_pmu_profile generate
+ because the value of __gcov_pmu_top_n_address is ignored when
+ not doing profiling. */
+ gcov_pmu_top_n_address_decl =
+ build_decl (VAR_DECL,
+ get_identifier ("__gcov_pmu_top_n_address"),
+ get_gcov_unsigned_t ());
+ TREE_PUBLIC (gcov_pmu_top_n_address_decl) = 1;
+ DECL_ARTIFICIAL (gcov_pmu_top_n_address_decl) = 1;
+ DECL_ONE_ONLY (gcov_pmu_top_n_address_decl) = 1;
+ TREE_STATIC (gcov_pmu_top_n_address_decl) = 1;
+ DECL_INITIAL (gcov_pmu_top_n_address_decl) =
+ build_int_cstu (get_gcov_unsigned_t (), top_n_addr);
+ assemble_variable (gcov_pmu_top_n_address_decl, 0, 0, 0);
+ }
+ pmu_profiling_initialized = 1;
}
/* Performs file-level cleanup. Close graph file, generate coverage
@@ -2038,6 +2181,10 @@ str_list_append (struct str_list **head, struct str_list **tail, const char *s)
*tail = e;
}
+extern bool is_kernel_build;
+
+#define KERNEL_BUILD_PREDEF_STRING "__KERNEL__"
+
/* Copies the macro def or undef CPP_DEF and saves the copy
in a list. IS_DEF is a flag indicating if CPP_DEF represents
a -D or -U. */
@@ -2050,6 +2197,11 @@ coverage_note_define (const char *cpp_def, bool is_def)
strcpy (s + 1, cpp_def);
str_list_append (&cpp_defines_head, &cpp_defines_tail, s);
num_cpp_defines++;
+
+ /* When -D__KERNEL__ is in the option list, we assume this is
+ compilation for Linux Kernel. */
+ if (!strcmp(cpp_def, KERNEL_BUILD_PREDEF_STRING))
+ is_kernel_build = is_def;
}
/* Copies the -imacro/-include FILENAME and saves the copy in a list. */
@@ -2130,5 +2282,19 @@ write_opts_to_asm (void)
dw2_asm_output_nstring (lipo_cl_args[i], -1, NULL);
}
-#include "gt-coverage.h"
+/* Check the command line OPTIONS passed to
+ -fpmu-profile-generate. Return 0 if the options are valid, non-zero
+ otherwise. */
+
+int
+check_pmu_profile_options (const char *options)
+{
+ if (strcmp(options, "load-latency") &&
+ strcmp(options, "load-latency-verbose") &&
+ strcmp(options, "branch-mispredict") &&
+ strcmp(options, "branch-mispredict-verbose"))
+ return 1;
+ return 0;
+}
+#include "gt-coverage.h"
diff --git a/gcc-4.4.3/gcc/coverage.h b/gcc-4.4.3/gcc/coverage.h
index 2562a1fa4..13abcb65e 100644
--- a/gcc-4.4.3/gcc/coverage.h
+++ b/gcc-4.4.3/gcc/coverage.h
@@ -58,6 +58,7 @@ extern gcov_type *get_coverage_counts_no_warn (struct function *,
extern struct cgraph_node * find_func_by_global_id (unsigned HOST_WIDE_INT gid);
+extern struct cgraph_node * find_func_by_name (const char *name);
/* All the coverage counters are supposed to be allocated by the time
coverage_end_function is called. However, direct-call counters are
allocated after coverage_end_function has been called. This function
@@ -72,8 +73,18 @@ extern bool coverage_function_present (unsigned fn_ident);
extern tree get_gcov_type (void);
extern tree get_gcov_unsigned_t (void);
+extern tree get_gcov_float_t (void);
/* Mark this module as containing asm statements. */
extern void coverage_has_asm_stmt (void);
+/* Get the da file name, given base file name. */
+extern char * get_da_file_name (const char *base_file_name);
+
+/* Check if the specified options are valid for pmu profilig. */
+extern int check_pmu_profile_options (const char *options);
+
+/* Defined in tree-profile.c. */
+extern void tree_init_instrumentation_sampling (void);
+
#endif
diff --git a/gcc-4.4.3/gcc/cp/call.c b/gcc-4.4.3/gcc/cp/call.c
index 2a85c6684..4eb1974c0 100644
--- a/gcc-4.4.3/gcc/cp/call.c
+++ b/gcc-4.4.3/gcc/cp/call.c
@@ -195,6 +195,8 @@ static conversion *direct_reference_binding (tree, conversion *);
static bool promoted_arithmetic_type_p (tree);
static conversion *conditional_conversion (tree, tree);
static char *name_as_c_string (tree, tree, bool *);
+static void find_const_memfunc_with_identical_prototype (tree,
+ struct z_candidate *);
static tree call_builtin_trap (void);
static tree prep_operand (tree);
static void add_candidates (tree, tree, tree, bool, tree, tree,
@@ -4159,7 +4161,20 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
if (resolve_args (arglist) == error_mark_node)
result = error_mark_node;
else
- result = build_over_call (cand, LOOKUP_NORMAL, complain);
+ {
+ result = build_over_call (cand, LOOKUP_NORMAL, complain);
+ /* If thread safety check is enabled and FN is not a const
+ member function, try to see if there is a const overload in
+ the candidates list (if we haven't done so already). */
+ if (warn_thread_safety
+ && DECL_FUNCTION_MEMBER_P (cand->fn)
+ && !DECL_CONST_MEMFUNC_P (cand->fn)
+ && (!DECL_ATTRIBUTES (cand->fn)
+ || !lookup_attribute ("has_const_overload",
+ DECL_ATTRIBUTES (cand->fn))))
+ find_const_memfunc_with_identical_prototype (cand->fn,
+ candidates);
+ }
}
else
{
@@ -4546,21 +4561,21 @@ conversion_null_warnings (tree totype, tree expr, tree fn, int argnum)
if (expr == null_node && TREE_CODE (t) != BOOLEAN_TYPE && ARITHMETIC_TYPE_P (t))
{
if (fn)
- warning (OPT_Wnull_conversion, "passing NULL to non-pointer argument %P of %qD",
+ warning (OPT_Wconversion_null, "passing NULL to non-pointer argument %P of %qD",
argnum, fn);
else
- warning (OPT_Wnull_conversion, "converting to non-pointer type %qT from NULL", t);
+ warning (OPT_Wconversion_null, "converting to non-pointer type %qT from NULL", t);
}
/* Issue warnings if "false" is converted to a NULL pointer */
else if (expr == boolean_false_node && POINTER_TYPE_P (t))
{
if (fn)
- warning (OPT_Wnull_conversion,
+ warning (OPT_Wconversion_null,
"converting %<false%> to pointer type for argument %P of %qD",
argnum, fn);
else
- warning (OPT_Wnull_conversion, "converting %<false%> to pointer type");
+ warning (OPT_Wconversion_null, "converting %<false%> to pointer type");
}
}
@@ -5882,6 +5897,53 @@ name_as_c_string (tree name, tree type, bool *free_p)
return pretty_name;
}
+/* Given a decl FN which is a non-const member function, try to find if
+ there is another candidate that is a const member function with the same
+ prototype (i.e. parameter list) as FN. And if found, attach an internal
+ attribute "has_const_overload" to FN. */
+
+static void
+find_const_memfunc_with_identical_prototype (tree fn,
+ struct z_candidate *candidates)
+{
+ bool find_const_overload = false;
+ struct z_candidate *cand;
+
+ for (cand = candidates; cand; cand = cand->next)
+ {
+ tree candfunc = cand->fn;
+ tree t1, t2;
+
+ /* candfunc (or cand->fn) can be an IDENTIFIER_NODE if the candidate
+ is a builtin (see the add_candidate call in build_builtin_candidate).
+ Since it's not a user-defined overload, just skip it. */
+ if (TREE_CODE (candfunc) != FUNCTION_DECL)
+ continue;
+
+ /* Skip FN itself and candidates that are not const. */
+ if (candfunc == fn || !DECL_CONST_MEMFUNC_P (candfunc))
+ continue;
+
+ /* Compare the parameter lists of FN and CANDFUNC. */
+ for (t1 = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn))),
+ t2 = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (candfunc)));
+ t1 && t2;
+ t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2))
+ if (t1 != t2)
+ break;
+
+ if (!t1 && !t2)
+ {
+ find_const_overload = true;
+ break;
+ }
+ }
+
+ if (find_const_overload)
+ DECL_ATTRIBUTES (fn) = tree_cons (get_identifier ("has_const_overload"),
+ NULL_TREE, DECL_ATTRIBUTES (fn));
+}
+
/* Build a call to "INSTANCE.FN (ARGS)". If FN_P is non-NULL, it will
be set, upon return, to the function called. */
@@ -6152,6 +6214,15 @@ build_new_method_call (tree instance, tree fns, tree args,
"operator delete(~X(f()))" (rather than generating
"t = f(), ~X(t), operator delete (t)"). */
call = build_nop (void_type_node, call);
+ /* If thread safety check is enabled and FN is not a const
+ member function, try to see if there is a const overload in
+ the candidates list (if we haven't done so already). */
+ if (warn_thread_safety
+ && !DECL_CONST_MEMFUNC_P (fn)
+ && (!DECL_ATTRIBUTES (fn)
+ || !lookup_attribute ("has_const_overload",
+ DECL_ATTRIBUTES (fn))))
+ find_const_memfunc_with_identical_prototype (fn, candidates);
}
}
}
diff --git a/gcc-4.4.3/gcc/cp/class.c b/gcc-4.4.3/gcc/cp/class.c
index d1b9bff4c..e7b78cc29 100644
--- a/gcc-4.4.3/gcc/cp/class.c
+++ b/gcc-4.4.3/gcc/cp/class.c
@@ -8090,4 +8090,22 @@ cp_decl_is_destructor (tree decl)
return DECL_DESTRUCTOR_P (decl);
}
+/* Return
+ 1 if decl is a const member function,
+ 2 if decl is not a const member function but has a const overload that
+ has identical parameter list,
+ 0 otherwise. */
+
+int
+cp_decl_is_const_member_func (tree decl)
+{
+ if (DECL_CONST_MEMFUNC_P (decl))
+ return 1;
+ else if (DECL_ATTRIBUTES (decl)
+ && lookup_attribute ("has_const_overload", DECL_ATTRIBUTES (decl)))
+ return 2;
+ else
+ return 0;
+}
+
#include "gt-cp-class.h"
diff --git a/gcc-4.4.3/gcc/cp/cp-lang.c b/gcc-4.4.3/gcc/cp/cp-lang.c
index ef7bd33af..4fe8c6727 100644
--- a/gcc-4.4.3/gcc/cp/cp-lang.c
+++ b/gcc-4.4.3/gcc/cp/cp-lang.c
@@ -1,5 +1,5 @@
/* Language-dependent hooks for C++.
- Copyright 2001, 2002, 2004, 2007, 2008 Free Software Foundation, Inc.
+ Copyright 2001, 2002, 2004, 2007, 2008, 2009 Free Software Foundation, Inc.
Contributed by Alexandre Oliva <aoliva@redhat.com>
This file is part of GCC.
@@ -80,6 +80,8 @@ static bool cp_is_global_delete_fndecl_p (tree);
#define LANG_HOOKS_DECL_IS_CONSTRUCTOR cp_decl_is_constructor
#undef LANG_HOOKS_DECL_IS_DESTRUCTOR
#define LANG_HOOKS_DECL_IS_DESTRUCTOR cp_decl_is_destructor
+#undef LANG_HOOKS_DECL_IS_CONST_MEMBER_FUNC
+#define LANG_HOOKS_DECL_IS_CONST_MEMBER_FUNC cp_decl_is_const_member_func
/* LIPO support. */
#undef LANG_HOOKS_ADD_BUILT_IN_DECL
@@ -163,7 +165,9 @@ cxx_dwarf_name (tree t, int verbosity)
gcc_assert (DECL_P (t));
if (verbosity >= 2)
- return decl_as_string (t, TFF_DECL_SPECIFIERS | TFF_UNQUALIFIED_NAME);
+ return decl_as_string (t,
+ TFF_DECL_SPECIFIERS | TFF_UNQUALIFIED_NAME
+ | TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS);
return cxx_printable_name (t, verbosity);
}
diff --git a/gcc-4.4.3/gcc/cp/cp-tree.h b/gcc-4.4.3/gcc/cp/cp-tree.h
index d8823152a..29948c97f 100644
--- a/gcc-4.4.3/gcc/cp/cp-tree.h
+++ b/gcc-4.4.3/gcc/cp/cp-tree.h
@@ -2258,6 +2258,24 @@ extern void decl_shadowed_for_var_insert (tree, tree);
#define TI_ARGS(NODE) (TREE_VALUE (NODE))
#define TI_PENDING_TEMPLATE_FLAG(NODE) TREE_LANG_FLAG_1 (NODE)
+/* For a given TREE_VEC containing a template argument list,
+ this property contains the number of arguments that are not
+ defaulted. */
+#define NON_DEFAULT_TEMPLATE_ARGS_COUNT(NODE) TREE_CHAIN (TREE_VEC_CHECK (NODE))
+/* Below are the setter and getter of the NON_DEFAULT_TEMPLATE_ARGS_COUNT
+ property. */
+#define SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT(NODE, INT_VALUE) \
+ NON_DEFAULT_TEMPLATE_ARGS_COUNT(NODE) = build_int_cst (NULL_TREE, INT_VALUE)
+#ifdef ENABLE_CHECKING
+#define GET_NON_DEFAULT_TEMPLATE_ARGS_COUNT(NODE) \
+ int_cst_value (NON_DEFAULT_TEMPLATE_ARGS_COUNT (NODE))
+#else
+#define GET_NON_DEFAULT_TEMPLATE_ARGS_COUNT(NODE) \
+ NON_DEFAULT_TEMPLATE_ARGS_COUNT (NODE) \
+ ? int_cst_value (NON_DEFAULT_TEMPLATE_ARGS_COUNT (NODE)) \
+ : TREE_VEC_LENGTH (INNERMOST_TEMPLATE_ARGS (NODE))
+#endif
+
/* We use TREE_VECs to hold template arguments. If there is only one
level of template arguments, then the TREE_VEC contains the
arguments directly. If there is more than one level of template
@@ -2268,7 +2286,13 @@ extern void decl_shadowed_for_var_insert (tree, tree);
It is incorrect to ever form a template argument vector containing
only one level of arguments, but which is a TREE_VEC containing as
- its only entry the TREE_VEC for that level. */
+ its only entry the TREE_VEC for that level.
+
+ For each TREE_VEC containing the template arguments for a single
+ level, it's possible to get or set the number of non defaulted
+ template arguments by using the accessor macros
+ GET_NON_DEFAULT_TEMPLATE_ARGS_COUNT or
+ SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT. */
/* Nonzero if the template arguments is actually a vector of vectors,
rather than just a vector. */
@@ -3584,6 +3608,8 @@ typedef enum tsubst_flags_t {
conversion. */
tf_no_access_control = 1 << 7, /* Do not perform access checks, even
when issuing other errors. */
+ /* Do not instantiate classes (used by count_non_default_template_args). */
+ tf_no_class_instantiations = 1 << 8,
/* Convenient substitution flags combinations. */
tf_warning_or_error = tf_warning | tf_error
} tsubst_flags_t;
@@ -3933,7 +3959,9 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, OP_FLAG, TYPENAME_FLAG };
TFF_EXPR_IN_PARENS: parenthesize expressions.
TFF_NO_FUNCTION_ARGUMENTS: don't show function arguments.
TFF_UNQUALIFIED_NAME: do not print the qualifying scope of the
- top-level entity. */
+ top-level entity.
+ TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS: do not omit template arguments
+ identical to their defaults. */
#define TFF_PLAIN_IDENTIFIER (0)
#define TFF_SCOPE (1)
@@ -3948,6 +3976,7 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, OP_FLAG, TYPENAME_FLAG };
#define TFF_EXPR_IN_PARENS (1 << 9)
#define TFF_NO_FUNCTION_ARGUMENTS (1 << 10)
#define TFF_UNQUALIFIED_NAME (1 << 11)
+#define TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS (1 << 12)
/* Returns the TEMPLATE_DECL associated to a TEMPLATE_TEMPLATE_PARM
node. */
@@ -4281,6 +4310,7 @@ extern tree cp_fold_obj_type_ref (tree, tree);
extern bool cp_decl_is_base_field (tree);
extern bool cp_decl_is_constructor (tree);
extern bool cp_decl_is_destructor (tree);
+extern int cp_decl_is_const_member_func (tree);
extern void set_linkage_according_to_type (tree, tree);
extern void determine_key_method (tree);
extern void check_for_override (tree, tree);
diff --git a/gcc-4.4.3/gcc/cp/cvt.c b/gcc-4.4.3/gcc/cp/cvt.c
index 28533092d..62f7a26f5 100644
--- a/gcc-4.4.3/gcc/cp/cvt.c
+++ b/gcc-4.4.3/gcc/cp/cvt.c
@@ -1116,7 +1116,7 @@ build_expr_type_conversion (int desires, tree expr, bool complain)
if (expr == null_node
&& (desires & WANT_INT)
&& !(desires & WANT_NULL))
- warning (OPT_Wnull_conversion, "converting NULL to non-pointer type");
+ warning (OPT_Wconversion_null, "converting NULL to non-pointer type");
basetype = TREE_TYPE (expr);
diff --git a/gcc-4.4.3/gcc/cp/error.c b/gcc-4.4.3/gcc/cp/error.c
index 727c2fdec..301a1693a 100644
--- a/gcc-4.4.3/gcc/cp/error.c
+++ b/gcc-4.4.3/gcc/cp/error.c
@@ -78,6 +78,8 @@ static void dump_template_bindings (tree, tree);
static void dump_scope (tree, int);
static void dump_template_parms (tree, int, int);
+static int get_non_default_template_args_count (tree, int);
+
static const char *function_category (tree);
static void maybe_print_instantiation_context (diagnostic_context *);
static void print_instantiation_full_context (diagnostic_context *);
@@ -151,17 +153,36 @@ dump_template_argument (tree arg, int flags)
}
}
+/* Count the number of template arguments ARGS whose value does not
+ match the (optional) default template parameter in PARAMS */
+
+static int
+get_non_default_template_args_count (tree args, int flags)
+{
+ int n = TREE_VEC_LENGTH (INNERMOST_TEMPLATE_ARGS (args));
+
+ if (/* We use this flag when generating debug information. We don't
+ want to expand templates at this point, for this may generate
+ new decls, which gets decl counts out of sync, which may in
+ turn cause codegen differences between compilations with and
+ without -g. */
+ (flags & TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS) != 0)
+ return n;
+
+ return GET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (INNERMOST_TEMPLATE_ARGS (args));
+}
+
/* Dump a template-argument-list ARGS (always a TREE_VEC) under control
of FLAGS. */
static void
dump_template_argument_list (tree args, int flags)
{
- int n = TREE_VEC_LENGTH (args);
+ int n = get_non_default_template_args_count (args, flags);
int need_comma = 0;
int i;
- for (i = 0; i< n; ++i)
+ for (i = 0; i < n; ++i)
{
tree arg = TREE_VEC_ELT (args, i);
@@ -237,18 +258,19 @@ dump_template_bindings (tree parms, tree args)
int lvl = TMPL_PARMS_DEPTH (parms);
int arg_idx = 0;
int i;
+ tree lvl_args = NULL_TREE;
+
+ /* Don't crash if we had an invalid argument list. */
+ if (TMPL_ARGS_DEPTH (args) >= lvl)
+ lvl_args = TMPL_ARGS_LEVEL (args, lvl);
for (i = 0; i < TREE_VEC_LENGTH (p); ++i)
{
tree arg = NULL_TREE;
/* Don't crash if we had an invalid argument list. */
- if (TMPL_ARGS_DEPTH (args) >= lvl)
- {
- tree lvl_args = TMPL_ARGS_LEVEL (args, lvl);
- if (NUM_TMPL_ARGS (lvl_args) > arg_idx)
- arg = TREE_VEC_ELT (lvl_args, arg_idx);
- }
+ if (lvl_args && NUM_TMPL_ARGS (lvl_args) > arg_idx)
+ arg = TREE_VEC_ELT (lvl_args, arg_idx);
if (need_comma)
pp_separate_with_comma (cxx_pp);
@@ -1332,16 +1354,13 @@ dump_template_parms (tree info, int primary, int flags)
pp_cxx_begin_template_argument_list (cxx_pp);
/* Be careful only to print things when we have them, so as not
- to crash producing error messages. */
+ to crash producing error messages. */
if (args && !primary)
{
int len, ix;
+ len = get_non_default_template_args_count (args, flags);
- if (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (args))
- args = TREE_VEC_ELT (args, TREE_VEC_LENGTH (args) - 1);
-
- len = TREE_VEC_LENGTH (args);
-
+ args = INNERMOST_TEMPLATE_ARGS (args);
for (ix = 0; ix != len; ix++)
{
tree arg = TREE_VEC_ELT (args, ix);
diff --git a/gcc-4.4.3/gcc/cp/lang-specs.h b/gcc-4.4.3/gcc/cp/lang-specs.h
index 54d69a115..cb396b1c9 100644
--- a/gcc-4.4.3/gcc/cp/lang-specs.h
+++ b/gcc-4.4.3/gcc/cp/lang-specs.h
@@ -47,7 +47,7 @@ along with GCC; see the file COPYING3. If not see
%(cpp_options) %2 -o %{save-temps:%b.ii} %{!save-temps:%g.ii} \n}\
cc1plus %{save-temps|no-integrated-cpp:-fpreprocessed %{save-temps:%b.ii} %{!save-temps:%g.ii}}\
%{!save-temps:%{!no-integrated-cpp:%(cpp_unique_options)}}\
- %(cc1_options) %2 %{+e1*}\
+ %(cc1_options) %(esp_options) %2 %{+e1*}\
%{!fsyntax-only:-o %g.s %{!o*:--output-pch=%i.gch} %W{o*:--output-pch=%*}%V}}}}",
CPLUSPLUS_CPP_SPEC, 0, 0},
{"@c++",
@@ -57,11 +57,11 @@ along with GCC; see the file COPYING3. If not see
%(cpp_options) %2 -o %{save-temps:%b.ii} %{!save-temps:%g.ii} \n}\
cc1plus %{save-temps|no-integrated-cpp:-fpreprocessed %{save-temps:%b.ii} %{!save-temps:%g.ii}}\
%{!save-temps:%{!no-integrated-cpp:%(cpp_unique_options)}}\
- %(cc1_options) %2 %{+e1*}\
+ %(cc1_options) %(esp_options) %2 %{+e1*}\
%{!fsyntax-only:%(invoke_as)}}}}",
CPLUSPLUS_CPP_SPEC, 0, 0},
{".ii", "@c++-cpp-output", 0, 0, 0},
{"@c++-cpp-output",
"%{!M:%{!MM:%{!E:\
- cc1plus -fpreprocessed %i %(cc1_options) %2 %{+e*}\
+ cc1plus -fpreprocessed %i %(cc1_options) %(esp_options) %2 %{+e*}\
%{!fsyntax-only:%(invoke_as)}}}}", 0, 0, 0},
diff --git a/gcc-4.4.3/gcc/cp/name-lookup.c b/gcc-4.4.3/gcc/cp/name-lookup.c
index ddc0afc8d..46b45ea66 100644
--- a/gcc-4.4.3/gcc/cp/name-lookup.c
+++ b/gcc-4.4.3/gcc/cp/name-lookup.c
@@ -4516,26 +4516,15 @@ add_function (struct arg_lookup *k, tree fn)
total number of functions being compared, which should usually be the
case. */
- /* We must find only functions, or exactly one non-function. */
- if (!k->functions)
+ if (!is_overloaded_fn (fn))
+ /* All names except those of (possibly overloaded) functions and
+ function templates are ignored. */;
+ else if (!k->functions)
k->functions = fn;
else if (fn == k->functions)
;
- else if (is_overloaded_fn (k->functions) && is_overloaded_fn (fn))
- k->functions = build_overload (fn, k->functions);
else
- {
- tree f1 = OVL_CURRENT (k->functions);
- tree f2 = fn;
- if (is_overloaded_fn (f1))
- {
- fn = f1; f1 = f2; f2 = fn;
- }
- error ("%q+D is not a function,", f1);
- error (" conflict with %q+D", f2);
- error (" in call to %qD", k->name);
- return true;
- }
+ k->functions = build_overload (fn, k->functions);
return false;
}
diff --git a/gcc-4.4.3/gcc/cp/parser.c b/gcc-4.4.3/gcc/cp/parser.c
index 9dff007bb..461f280da 100644
--- a/gcc-4.4.3/gcc/cp/parser.c
+++ b/gcc-4.4.3/gcc/cp/parser.c
@@ -6472,6 +6472,16 @@ cp_parser_question_colon_clause (cp_parser* parser, tree logical_or_expr)
tf_warning_or_error);
}
+/* A helpfer function to check if the given expression (EXPR) is of POD type.
+ Note that if the expression's type is NULL (e.g. when its type depends on
+ template parameters), we return false. */
+
+static bool
+expr_is_pod (tree expr)
+{
+ return TREE_TYPE (expr) && pod_type_p (TREE_TYPE (expr));
+}
+
/* Parse an assignment-expression.
assignment-expression:
@@ -6529,8 +6539,12 @@ cp_parser_assignment_expression (cp_parser* parser, bool cast_p,
return error_mark_node;
/* Check for and warn about self-assignment if -Wself-assign is
- enabled and the assignment operator is "=". */
- if (warn_self_assign && assignment_operator == NOP_EXPR)
+ enabled and the assignment operator is "=".
+ Checking for non-POD self-assignment will be performed only
+ when -Wself-assign-non-pod is enabled. */
+ if (warn_self_assign
+ && assignment_operator == NOP_EXPR
+ && (warn_self_assign_non_pod || expr_is_pod (expr)))
check_for_self_assign (input_location, expr, rhs);
/* Build the assignment expression. */
@@ -10615,6 +10629,9 @@ cp_parser_template_argument_list (cp_parser* parser)
parser->non_integral_constant_expression_p = saved_non_ice_p;
parser->integral_constant_expression_p = saved_ice_p;
parser->in_template_argument_list_p = saved_in_template_argument_list_p;
+#ifdef ENABLE_CHECKING
+ SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (vec, TREE_VEC_LENGTH (vec));
+#endif
return vec;
}
@@ -17896,6 +17913,35 @@ cp_parser_function_definition_from_specifiers_and_declarator
might be a friend. */
perform_deferred_access_checks ();
+ /* If the function definition is annotated with lock attributes with
+ arguments that are data members in the class, the parser would not be
+ able to bind those names to their FIELD_DECLs earlier when parsing the
+ attributes because the class context was not in scope at that time.
+ Now that we have entered the class context, try and bind and resolve
+ those identifiers. */
+ if (attributes)
+ {
+ tree attr;
+ for (attr = attributes; attr; attr = TREE_CHAIN (attr))
+ {
+ tree arg;
+ if (!is_lock_attribute_with_args (TREE_PURPOSE (attr)))
+ continue;
+ for (arg = TREE_VALUE (attr); arg; arg = TREE_CHAIN (arg))
+ {
+ tree lock = TREE_VALUE (arg);
+ if (TREE_CODE (lock) == IDENTIFIER_NODE)
+ {
+ tree lock_decl =
+ cp_parser_lookup_name_simple (parser, lock,
+ input_location);
+ if (lock_decl && lock_decl != error_mark_node)
+ TREE_VALUE (arg) = lock_decl;
+ }
+ }
+ }
+ }
+
if (!success_p)
{
/* Skip the entire function. */
diff --git a/gcc-4.4.3/gcc/cp/pt.c b/gcc-4.4.3/gcc/cp/pt.c
index 663d42037..57e5884ed 100644
--- a/gcc-4.4.3/gcc/cp/pt.c
+++ b/gcc-4.4.3/gcc/cp/pt.c
@@ -87,6 +87,12 @@ struct pending_attribute GTY (()) {
static GTY(()) struct pending_attribute *pending_lock_attributes = NULL;
+typedef struct pending_attribute *pending_attribute_p;
+DEF_VEC_P(pending_attribute_p);
+DEF_VEC_ALLOC_P(pending_attribute_p,gc);
+
+static GTY(()) VEC(pending_attribute_p,gc) *pending_lock_attr_stack;
+
int processing_template_parmlist;
static int template_header_count;
@@ -2809,6 +2815,7 @@ expand_template_argument_pack (tree args)
tree result_args = NULL_TREE;
int in_arg, out_arg = 0, nargs = args ? TREE_VEC_LENGTH (args) : 0;
int num_result_args = -1;
+ int non_default_args_count = -1;
/* First, determine if we need to expand anything, and the number of
slots we'll need. */
@@ -2838,6 +2845,9 @@ expand_template_argument_pack (tree args)
/* Expand arguments. */
result_args = make_tree_vec (num_result_args);
+ if (NON_DEFAULT_TEMPLATE_ARGS_COUNT (args))
+ non_default_args_count =
+ GET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (args);
for (in_arg = 0; in_arg < nargs; ++in_arg)
{
tree arg = TREE_VEC_ELT (args, in_arg);
@@ -2847,6 +2857,8 @@ expand_template_argument_pack (tree args)
int i, num_packed = TREE_VEC_LENGTH (packed);
for (i = 0; i < num_packed; ++i, ++out_arg)
TREE_VEC_ELT (result_args, out_arg) = TREE_VEC_ELT(packed, i);
+ if (non_default_args_count > 0)
+ non_default_args_count += num_packed;
}
else
{
@@ -2854,7 +2866,8 @@ expand_template_argument_pack (tree args)
++out_arg;
}
}
-
+ if (non_default_args_count >= 0)
+ SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (result_args, non_default_args_count);
return result_args;
}
@@ -3213,6 +3226,10 @@ current_template_args (void)
/* Turn this argument into a TYPE_ARGUMENT_PACK
with a single element, which expands T. */
tree vec = make_tree_vec (1);
+#ifdef ENABLE_CHECKING
+ SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT
+ (vec, TREE_VEC_LENGTH (vec));
+#endif
TREE_VEC_ELT (vec, 0) = make_pack_expansion (t);
t = make_node (TYPE_ARGUMENT_PACK);
@@ -3229,6 +3246,10 @@ current_template_args (void)
with a single element, which expands T. */
tree vec = make_tree_vec (1);
tree type = TREE_TYPE (TEMPLATE_PARM_DECL (t));
+#ifdef ENABLE_CHECKING
+ SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT
+ (vec, TREE_VEC_LENGTH (vec));
+#endif
TREE_VEC_ELT (vec, 0) = make_pack_expansion (t);
t = make_node (NONTYPE_ARGUMENT_PACK);
@@ -3241,6 +3262,10 @@ current_template_args (void)
}
}
+#ifdef ENABLE_CHECKING
+ SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (a, TREE_VEC_LENGTH (a));
+#endif
+
if (length > 1)
TREE_VEC_ELT (args, --l) = a;
else
@@ -5300,6 +5325,10 @@ coerce_template_parameter_pack (tree parms,
}
SET_ARGUMENT_PACK_ARGS (argument_pack, packed_args);
+#ifdef ENABLE_CHECKING
+ SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (packed_args,
+ TREE_VEC_LENGTH (packed_args));
+#endif
return argument_pack;
}
@@ -5452,9 +5481,16 @@ coerce_template_parms (tree parms,
}
}
else if (require_all_args)
- /* There must be a default arg in this case. */
- arg = tsubst_template_arg (TREE_PURPOSE (parm), new_args,
- complain, in_decl);
+ {
+ /* There must be a default arg in this case. */
+ arg = tsubst_template_arg (TREE_PURPOSE (parm), new_args,
+ complain, in_decl);
+ /* The position of the first default template argument,
+ is also the number of non-defaulted arguments in NEW_INNER_ARGS.
+ Record that. */
+ if (!NON_DEFAULT_TEMPLATE_ARGS_COUNT (new_inner_args))
+ SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (new_inner_args, arg_idx);
+ }
else
break;
@@ -5484,6 +5520,12 @@ coerce_template_parms (tree parms,
if (lost)
return error_mark_node;
+#ifdef ENABLE_CHECKING
+ if (!NON_DEFAULT_TEMPLATE_ARGS_COUNT (new_inner_args))
+ SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (new_inner_args,
+ TREE_VEC_LENGTH (new_inner_args));
+#endif
+
return new_inner_args;
}
@@ -7102,12 +7144,18 @@ instantiate_class_template (tree type)
push_to_top_level ();
+ /* Push the existing pending lock attributes to the stack. */
+ VEC_safe_push (pending_attribute_p, gc, pending_lock_attr_stack,
+ pending_lock_attributes);
+ pending_lock_attributes = NULL;
+
SET_CLASSTYPE_INTERFACE_UNKNOWN (type);
- /* Set the input location to the template definition. This is needed
- if tsubsting causes an error. */
- typedecl = TYPE_MAIN_DECL (type);
- input_location = DECL_SOURCE_LOCATION (typedecl);
+ /* Set the input location to the most specialized template definition.
+ This is needed if tsubsting causes an error. */
+ typedecl = TYPE_MAIN_DECL (pattern);
+ input_location = DECL_SOURCE_LOCATION (TYPE_NAME (type)) =
+ DECL_SOURCE_LOCATION (typedecl);
TYPE_HAS_USER_CONSTRUCTOR (type) = TYPE_HAS_USER_CONSTRUCTOR (pattern);
TYPE_HAS_NEW_OPERATOR (type) = TYPE_HAS_NEW_OPERATOR (pattern);
@@ -7528,10 +7576,13 @@ instantiate_class_template (tree type)
cplus_decl_attributes (&pa->decl, t, pa->attr_flags);
}
parsing_lock_attribute = false;
- pending_lock_attributes = NULL;
input_location = saved_location;
}
+ /* Pop out the pending attributes of the outer class/template. */
+ pending_lock_attributes = VEC_pop (pending_attribute_p,
+ pending_lock_attr_stack);
+
pop_nested_class ();
pop_from_top_level ();
pop_deferring_access_checks ();
@@ -7964,6 +8015,19 @@ tsubst_template_args (tree t, tree args, tsubst_flags_t complain, tree in_decl)
/* Make space for the expanded arguments coming from template
argument packs. */
t = make_tree_vec (len + expanded_len_adjust);
+ /* ORIG_T can contain TREE_VECs. That happens if ORIG_T contains the
+ arguments for a member template.
+ In that case each TREE_VEC in ORIG_T represents a level of template
+ arguments, and ORIG_T won't carry any non defaulted argument count.
+ It will rather be the nested TREE_VECs that will carry one.
+ In other words, ORIG_T carries a non defaulted argument count only
+ if it doesn't contain any nested TREE_VEC. */
+ if (NON_DEFAULT_TEMPLATE_ARGS_COUNT (orig_t))
+ {
+ int count = GET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (orig_t);
+ count += expanded_len_adjust;
+ SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (t, count);
+ }
for (i = 0, out = 0; i < len; i++)
{
if ((PACK_EXPANSION_P (TREE_VEC_ELT (orig_t, i))
@@ -9821,7 +9885,8 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
But, such constructs have already been resolved by this
point, so here CTX really should have complete type, unless
it's a partial instantiation. */
- ctx = complete_type (ctx);
+ if (!(complain & tf_no_class_instantiations))
+ ctx = complete_type (ctx);
if (!COMPLETE_TYPE_P (ctx))
{
if (complain & tf_error)
@@ -12604,6 +12669,10 @@ type_unification_real (tree tparms,
gcc_assert (!xargs || TREE_CODE (xargs) == TREE_LIST);
gcc_assert (ntparms > 0);
+ /* Reset the number of non-defaulted template arguments contained
+ in in TARGS. */
+ NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs) = NULL_TREE;
+
switch (strict)
{
case DEDUCE_CALL:
@@ -12789,6 +12858,11 @@ type_unification_real (tree tparms,
else
{
TREE_VEC_ELT (targs, i) = arg;
+ /* The position of the first default template argument,
+ is also the number of non-defaulted arguments in TARGS.
+ Record that. */
+ if (!NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs))
+ SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs, i);
continue;
}
}
@@ -12816,6 +12890,10 @@ type_unification_real (tree tparms,
return 2;
}
+#ifdef ENABLE_CHECKING
+ if (!NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs))
+ SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs, TREE_VEC_LENGTH (targs));
+#endif
return 0;
}
@@ -15575,6 +15653,8 @@ instantiate_decl (tree d, int defer_ok,
&& !DECL_NOT_REALLY_EXTERN (d))
mark_definable (d);
+ DECL_SOURCE_LOCATION (td) = DECL_SOURCE_LOCATION (code_pattern);
+ DECL_SOURCE_LOCATION (d) = DECL_SOURCE_LOCATION (code_pattern);
input_location = DECL_SOURCE_LOCATION (d);
/* If D is a member of an explicitly instantiated class template,
diff --git a/gcc-4.4.3/gcc/cp/typeck2.c b/gcc-4.4.3/gcc/cp/typeck2.c
index 021f11f3f..3ac21948f 100644
--- a/gcc-4.4.3/gcc/cp/typeck2.c
+++ b/gcc-4.4.3/gcc/cp/typeck2.c
@@ -451,13 +451,15 @@ cxx_incomplete_type_error (const_tree value, const_tree type)
expression to which INIT should be assigned. INIT is a CONSTRUCTOR. */
static void
-split_nonconstant_init_1 (tree dest, tree init)
+split_nonconstant_init_1 (tree dest, tree *initp)
{
unsigned HOST_WIDE_INT idx;
+ tree init = *initp;
tree field_index, value;
tree type = TREE_TYPE (dest);
tree inner_type = NULL;
bool array_type_p = false;
+ HOST_WIDE_INT num_type_elements, num_initialized_elements;
switch (TREE_CODE (type))
{
@@ -469,6 +471,7 @@ split_nonconstant_init_1 (tree dest, tree init)
case RECORD_TYPE:
case UNION_TYPE:
case QUAL_UNION_TYPE:
+ num_initialized_elements = 0;
FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (init), idx,
field_index, value)
{
@@ -491,12 +494,13 @@ split_nonconstant_init_1 (tree dest, tree init)
sub = build3 (COMPONENT_REF, inner_type, dest, field_index,
NULL_TREE);
- split_nonconstant_init_1 (sub, value);
+ split_nonconstant_init_1 (sub, &value);
}
else if (!initializer_constant_valid_p (value, inner_type))
{
tree code;
tree sub;
+ HOST_WIDE_INT inner_elements;
/* FIXME: Ordered removal is O(1) so the whole function is
worst-case quadratic. This could be fixed using an aside
@@ -519,9 +523,22 @@ split_nonconstant_init_1 (tree dest, tree init)
code = build2 (INIT_EXPR, inner_type, sub, value);
code = build_stmt (EXPR_STMT, code);
add_stmt (code);
+
+ inner_elements = count_type_elements (inner_type, true);
+ if (inner_elements < 0)
+ num_initialized_elements = -1;
+ else if (num_initialized_elements >= 0)
+ num_initialized_elements += inner_elements;
continue;
}
}
+
+ num_type_elements = count_type_elements (type, true);
+ /* If all elements of the initializer are non-constant and
+ have been split out, we don't need the empty CONSTRUCTOR. */
+ if (num_type_elements > 0
+ && num_type_elements == num_initialized_elements)
+ *initp = NULL;
break;
case VECTOR_TYPE:
@@ -557,7 +574,7 @@ split_nonconstant_init (tree dest, tree init)
if (TREE_CODE (init) == CONSTRUCTOR)
{
code = push_stmt_list ();
- split_nonconstant_init_1 (dest, init);
+ split_nonconstant_init_1 (dest, &init);
code = pop_stmt_list (code);
DECL_INITIAL (dest) = init;
TREE_READONLY (dest) = 0;
diff --git a/gcc-4.4.3/gcc/dbgcnt.def b/gcc-4.4.3/gcc/dbgcnt.def
index aeeeeaa2f..4b904e4c6 100644
--- a/gcc-4.4.3/gcc/dbgcnt.def
+++ b/gcc-4.4.3/gcc/dbgcnt.def
@@ -164,6 +164,7 @@ DEBUG_COUNTER (if_conversion)
DEBUG_COUNTER (if_after_combine)
DEBUG_COUNTER (if_after_reload)
DEBUG_COUNTER (inl)
+DEBUG_COUNTER (ivopts)
DEBUG_COUNTER (jump_bypass)
DEBUG_COUNTER (local_alloc_for_sched)
DEBUG_COUNTER (lrs)
diff --git a/gcc-4.4.3/gcc/doc/extend.texi b/gcc-4.4.3/gcc/doc/extend.texi
index 02c2725a5..4f247f4c0 100644
--- a/gcc-4.4.3/gcc/doc/extend.texi
+++ b/gcc-4.4.3/gcc/doc/extend.texi
@@ -2635,6 +2635,10 @@ as non-null, and the @option{-Wnonnull} option is enabled, a warning
is issued. The compiler may also choose to make optimizations based
on the knowledge that certain function arguments will not be null.
+Since non-static C++ methods have an implicit @code{this} argument, the
+arguments of such methods should be counted from two, not one, when
+giving values for @var{arg-index}.
+
If no argument index list is given to the @code{nonnull} attribute,
all pointer arguments are marked as non-null. To illustrate, the
following declaration is equivalent to the previous example:
@@ -2721,6 +2725,28 @@ compiled with more aggressive optimization options that produce faster
and larger code, while other functions can be called with less
aggressive options.
+@item pcs
+@cindex @code{pcs} function attribute
+
+The @code{pcs} attribute can be used to control the calling convention
+used for a function on ARM. The attribute takes an argument that specifies
+the calling convention to use.
+
+When compiling using the AAPCS ABI (or a variant of that) then valid
+values for the argument are @code{"aapcs"} and @code{"aapcs-vfp"}. In
+order to use a variant other than @code{"aapcs"} then the compiler must
+be permitted to use the appropriate co-processor registers (i.e., the
+VFP registers must be available in order to use @code{"aapcs-vfp"}).
+For example,
+
+@smallexample
+/* Argument passed in r0, and result returned in r0+r1. */
+double f2d (float) __attribute__((pcs("aapcs")));
+@end smallexample
+
+Variadic functions always use the @code{"aapcs"} calling convention and
+the compiler will reject attempts to specify an alternative.
+
@item pure
@cindex @code{pure} function attribute
Many functions have no effects except the return value and their
@@ -3022,6 +3048,11 @@ Enable/disable the generation of the SSE4A instructions.
@cindex @code{target("sse5")} attribute
Enable/disable the generation of the SSE5 instructions.
+@item lwp
+@itemx no-lwp
+@cindex @code{target("lwp")} attribute
+Enable/disable the generation of the LWP instructions.
+
@item ssse3
@itemx no-ssse3
@cindex @code{target("ssse3")} attribute
@@ -8704,6 +8735,23 @@ v2di __builtin_ia32_protq_imm (v2di, int)
v8hi __builtin_ia32_protw_imm (v8hi, int)
@end smallexample
+The following built-in functions are available when @option{-mlwp} is used.
+
+@smallexample
+void __builtin_ia32_llwpcb16 (void *);
+void __builtin_ia32_llwpcb32 (void *);
+void __builtin_ia32_llwpcb64 (void *);
+void * __builtin_ia32_llwpcb16 (void);
+void * __builtin_ia32_llwpcb32 (void);
+void * __builtin_ia32_llwpcb64 (void);
+void __builtin_ia32_lwpval16 (unsigned short, unsigned int, unsigned short)
+void __builtin_ia32_lwpval32 (unsigned int, unsigned int, unsigned int)
+void __builtin_ia32_lwpval64 (unsigned __int64, unsigned int, unsigned int)
+unsigned char __builtin_ia32_lwpins16 (unsigned short, unsigned int, unsigned short)
+unsigned char __builtin_ia32_lwpins32 (unsigned int, unsigned int, unsigned int)
+unsigned char __builtin_ia32_lwpins64 (unsigned __int64, unsigned int, unsigned int)
+@end smallexample
+
The following built-in functions are available when @option{-m3dnow} is used.
All of them generate the machine instruction that is part of the name.
diff --git a/gcc-4.4.3/gcc/doc/gcov.texi b/gcc-4.4.3/gcc/doc/gcov.texi
index 0225b1973..3c9eeafda 100644
--- a/gcc-4.4.3/gcc/doc/gcov.texi
+++ b/gcc-4.4.3/gcc/doc/gcov.texi
@@ -124,9 +124,11 @@ gcov [@option{-v}|@option{--version}] [@option{-h}|@option{--help}]
[@option{-a}|@option{--all-blocks}]
[@option{-b}|@option{--branch-probabilities}]
[@option{-c}|@option{--branch-counts}]
+ [@option{-m}|@option{--pmu-profile}]
[@option{-n}|@option{--no-output}]
[@option{-l}|@option{--long-file-names}]
[@option{-p}|@option{--preserve-paths}]
+ [@option{-q}|@option{--pmu_profile-path}]
[@option{-f}|@option{--function-summaries}]
[@option{-o}|@option{--object-directory} @var{directory|file}] @var{sourcefiles}
[@option{-u}|@option{--unconditional-branches}]
@@ -168,6 +170,14 @@ be shown, unless the @option{-u} option is given.
Write branch frequencies as the number of branches taken, rather than
the percentage of branches taken.
+@item -m
+@itemx --pmu-profile
+Output the additional PMU profile information if available.
+
+@item -q
+@itemx --pmu_profile-path
+PMU profile path (default @file{pmuprofile.gcda}).
+
@item -n
@itemx --no-output
Do not create the @command{gcov} output file.
diff --git a/gcc-4.4.3/gcc/doc/install.texi b/gcc-4.4.3/gcc/doc/install.texi
index fe45f893c..b2f6c4c93 100644
--- a/gcc-4.4.3/gcc/doc/install.texi
+++ b/gcc-4.4.3/gcc/doc/install.texi
@@ -1112,6 +1112,11 @@ of the arguments depend on the target.
Specify if the compiler should default to @option{-marm} or @option{-mthumb}.
This option is only supported on ARM targets.
+@item --with-fpmath=sse
+Specify if the compiler should default to @option{-msse2} and
+@option{-mfpmath=sse}. This option is only supported on i386 and
+x86-64 targets.
+
@item --with-divide=@var{type}
Specify how the compiler should generate code for checking for
division by zero. This option is only supported on the MIPS target.
diff --git a/gcc-4.4.3/gcc/doc/invoke.texi b/gcc-4.4.3/gcc/doc/invoke.texi
index 8f7e654c8..f35cee8b1 100644
--- a/gcc-4.4.3/gcc/doc/invoke.texi
+++ b/gcc-4.4.3/gcc/doc/invoke.texi
@@ -245,16 +245,16 @@ Objective-C and Objective-C++ Dialects}.
-Wno-int-to-pointer-cast -Wno-invalid-offsetof @gol
-Winvalid-pch -Wlarger-than=@var{len} -Wunsafe-loop-optimizations @gol
-Wlogical-op -Wlong-long @gol
--Wmain -Wmissing-braces -Wmissing-field-initializers @gol
+-Wmain -Wmaybe-uninitialized -Wmissing-braces -Wmissing-field-initializers @gol
-Wmissing-format-attribute -Wmissing-include-dirs @gol
-Wmissing-noreturn -Wno-mudflap @gol
--Wno-multichar -Wnonnull -Wno-overflow -Wnull-conversion @gol
+-Wno-multichar -Wnonnull -Wno-overflow -Wconversion-null @gol
-Woverlength-strings -Wpacked -Wpacked-bitfield-compat -Wpadded @gol
-Wparentheses -Wpedantic-ms-format -Wno-pedantic-ms-format @gol
-Wpointer-arith -Wno-pointer-to-int-cast @gol
-Wreal-conversion -Wredundant-decls @gol
--Wreturn-type -Wripa-opt-mismatch -Wself-assign -Wsequence-point @gol
--Wshadow -Wshadow-compatible-local -Wshadow-local @gol
+-Wreturn-type -Wripa-opt-mismatch -Wself-assign -Wself-assign-non-pod @gol
+-Wsequence-point -Wshadow -Wshadow-compatible-local -Wshadow-local @gol
-Wsign-compare -Wsign-conversion -Wstack-protector @gol
-Wstrict-aliasing -Wstrict-aliasing=n @gol
-Wstrict-overflow -Wstrict-overflow=@var{n} @gol
@@ -329,13 +329,15 @@ Objective-C and Objective-C++ Dialects}.
-falign-labels[=@var{n}] -falign-loops[=@var{n}] -fassociative-math @gol
-fauto-inc-dec -fbranch-probabilities -fbranch-target-load-optimize @gol
-fbranch-target-load-optimize2 -fbtr-bb-exclusive -fcaller-saves @gol
--fcheck-data-deps -fconserve-stack -fcprop-registers -fcrossjumping @gol
+-fcgraph-section -fcheck-data-deps @gol
+-fconserve-stack -fcprop-registers -fcrossjumping @gol
-fcse-follow-jumps -fcse-skip-blocks -fcx-fortran-rules -fcx-limited-range @gol
-fdata-sections -fdce -fdce @gol
-fdelayed-branch -fdelete-null-pointer-checks -fdse -fdse @gol
-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
+-ffunction-sections -ffvpt -ffvpt-functions=@var{ffvptfunctions} -fgcse @gol
+-fgcse-after-reload -fgcse-las -fgcse-lm @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-cp-clone -fipa-matrix-reorg -fipa-pta @gol
@@ -355,14 +357,16 @@ Objective-C and Objective-C++ Dialects}.
-fomit-frame-pointer -foptimize-register-move -foptimize-sibling-calls @gol
-fpeel-loops -fpredictive-commoning -fprefetch-loop-arrays @gol
-fprofile-correction -fprofile-dir=@var{path} -fprofile-generate @gol
--fprofile-generate=@var{path} @gol
+-fprofile-generate=@var{path} -fprofile-generate-sampling @gol
-fprofile-use -fprofile-use=@var{path} -fprofile-values @gol
+-fpmu-profile-generate=@var{pmuoption} @gol
+-fpmu-profile-use=@var{pmuoption} @gol
-freciprocal-math -fregmove -frename-registers -freorder-blocks @gol
-freorder-blocks-and-partition -freorder-functions @gol
-frerun-cse-after-loop -freschedule-modulo-scheduled-loops @gol
--fripa -fripa-disallow-asm-modules @gol
--fripa-disallow-opt-mismatch -fripa-verbose -frounding-math @gol
--fsample-profile -fsample-profile-aggregate-using @gol
+-fripa -fripa-disallow-asm-modules -fripa-disallow-opt-mismatch @gol
+-fripa-no-promote-always-inline-func -fripa-verbose @gol
+-frounding-math -fsample-profile -fsample-profile-aggregate-using @gol
-fsample-profile-use-entry -fsched2-use-superblocks @gol
-fsched2-use-traces -fsched-spec-load -fsched-spec-load-dangerous @gol
-fsched-stalled-insns-dep[=@var{n}] -fsched-stalled-insns[=@var{n}] @gol
@@ -583,17 +587,17 @@ Objective-C and Objective-C++ Dialects}.
-mno-wide-multiply -mrtd -malign-double @gol
-mpreferred-stack-boundary=@var{num}
-mincoming-stack-boundary=@var{num}
--mcld -mcx16 -msahf -mrecip @gol
+-mcld -mcx16 -msahf -mmovbe -mrecip @gol
-mmmx -msse -msse2 -msse3 -mssse3 -msse4.1 -msse4.2 -msse4 -mavx @gol
-maes -mpclmul @gol
--msse4a -m3dnow -mpopcnt -mabm -msse5 @gol
+-msse4a -m3dnow -mpopcnt -mabm -msse5 -mlwp @gol
-mthreads -mno-align-stringops -minline-all-stringops @gol
-minline-stringops-dynamically -minline-compares @gol
-mstringop-strategy=@var{alg} -mpush-args -maccumulate-outgoing-args @gol
-m128bit-long-double -m96bit-long-double -mregparm=@var{num} -msseregparm @gol
-mveclibabi=@var{type} -mpc32 -mpc64 -mpc80 -mstackrealign @gol
-momit-leaf-frame-pointer -mno-red-zone -mno-tls-direct-seg-refs @gol
--mcmodel=@var{code-model} @gol
+-mcmodel=@var{code-model} -mabi=@var{name} @gol
-m32 -m64 -mlarge-data-threshold=@var{num} @gol
-mfused-madd -mno-fused-madd -msse2avx}
@@ -2786,6 +2790,7 @@ Options} and @ref{Objective-C and Objective-C++ Dialect Options}.
-Wcomment @gol
-Wformat @gol
-Wmain @r{(only for C/ObjC and unless} @option{-ffreestanding}@r{)} @gol
+-Wmaybe-uninitialized @gol
-Wmissing-braces @gol
-Wnonnull @gol
-Wparentheses @gol
@@ -2834,6 +2839,7 @@ name is still supported, but the newer name is more descriptive.)
-Wsign-compare @gol
-Wtype-limits @gol
-Wuninitialized @gol
+-Wmaybe-uninitialized @gol
-Wunused-parameter @r{(only with} @option{-Wunused} @r{or} @option{-Wall}@r{)} @gol
}
@@ -2978,7 +2984,7 @@ Enable @option{-Wformat} plus format checks not included in
@option{-Wformat}. Currently equivalent to @samp{-Wformat
-Wformat-nonliteral -Wformat-security -Wformat-y2k}.
-@item -Wnonnull @r{(C and Objective-C only)}
+@item -Wnonnull @r{(C, C++, Objective-C, and Objective-C++ only)}
@opindex Wnonnull
@opindex Wno-nonnull
Warn about passing a null pointer for arguments marked as
@@ -3193,12 +3199,22 @@ void func()
@end group
@end smallexample
+In C++ it will not warn on self-assignment of non-POD variables unless
+@option{-Wself-assign-non-pod} is also enabled.
+
+@item -Wself-assign-non-pod
+@opindex Wself-assign-non-pod
+@opindex Wno-self-assign-non-pod
+Warn about self-assignment of non-POD variables. This is a C++-specific
+warning and only effective when @option{-Wself-assign} is enabled.
+
There are cases where self-assignment might be intentional. For example,
-a C++ programmers might write code to test whether an overloaded
+a C++ programmer might write code to test whether an overloaded
@code{operator=} works when the same object is assigned to itself.
-One way to work around the self-assign warning in such case is using
-the functional form @code{object.operator=(object)} instead of the
-assignment form @code{object = object}, as shown in the following example.
+One way to work around the self-assign warning in such cases when this flag
+is enabled is using the functional form @code{object.operator=(object)}
+instead of the assignment form @code{object = object}, as shown in the
+following example.
@smallexample
@group
@@ -3358,8 +3374,15 @@ to compute a value that itself is never used, because such
computations may be deleted by data flow analysis before the warnings
are printed.
-These warnings are made optional because GCC is not smart
-enough to see all the reasons why the code might be correct
+@item -Wmaybe-uninitialized
+@opindex Wmaybe-uninitialized
+@opindex Wno-maybe-uninitialized
+For an automatic variable, if there exists a path from the function
+entry to a use of the variable that is initialized, but there exist
+some other paths the variable is not initialized, the compiler will
+emit a warning if it can not prove the uninitialized paths do not
+happen at runtime. These warnings are made optional because GCC is
+not smart enough to see all the reasons why the code might be correct
despite appearing to have an error. Here is one example of how
this can happen:
@@ -3382,20 +3405,9 @@ this can happen:
@noindent
If the value of @code{y} is always 1, 2 or 3, then @code{x} is
-always initialized, but GCC doesn't know this. Here is
-another common case:
-
-@smallexample
-@{
- int save_y;
- if (change_y) save_y = y, y = new_y;
- @dots{}
- if (change_y) y = save_y;
-@}
-@end smallexample
-
-@noindent
-This has no bug because @code{save_y} is used only if it is set.
+always initialized, but GCC doesn't know this. To suppress the
+warning, the user needs to provide a default case with assert(0) or
+similar code.
@cindex @code{longjmp} warnings
This option also warns when a non-volatile automatic variable might be
@@ -3857,9 +3869,9 @@ to them. Warnings about conversions between signed and unsigned
integers are disabled by default in C++ unless
@option{-Wsign-conversion} is explicitly enabled.
-@item -Wnull-conversion
-@opindex Wnull-conversion
-@opindex Wno-null-conversion
+@item -Wconversion-null
+@opindex Wconversion-null
+@opindex Wno-conversion-null
Warn about peculiar, but valid, conversions from/to @code{NULL}.
This includes converting @code{NULL} to non-pointer type and
converting the boolean value @code{false} to @code{NULL}. This warning
@@ -6975,6 +6987,20 @@ The following options are enabled: @code{-fprofile-arcs}, @code{-fprofile-values
If @var{path} is specified, GCC will look at the @var{path} to find
the profile feedback data files. See @option{-fprofile-dir}.
+@item -fprofile-generate-sampling
+@opindex -fprofile-generate-sampling
+
+Enable sampling for instrumented binaries. Instead of recording every event,
+record only every N-th event, where N (the sampling rate) can be set either
+at compile time using
+@option{--param profile-generate-sampling-rate=@var{value}}, or
+at execution start time through environment variable @samp{GCOV_SAMPLING_RATE}.
+
+At this time sampling applies only to branch counters. A sampling rate of 100
+decreases instrumentated binary slowdown from up to 20x for heavily threaded
+applications down to around 2x. @option{-fprofile-correction} is always
+needed with sampling.
+
@item -fprofile-use
@itemx -fprofile-use=@var{path}
@opindex fprofile-use
@@ -6992,6 +7018,35 @@ code.
If @var{path} is specified, GCC will look at the @var{path} to find
the profile feedback data files. See @option{-fprofile-dir}.
+@item -fpmu-profile-generate=@var{pmuoption}
+@opindex fpmu-profile-generate
+
+Enable performance monitoring unit (PMU) profiling. This collects
+hardware counter data corresponding to @var{pmuoption}. Currently
+only @var{load-latency} and @var{branch-mispredict} are supported
+using pfmon tool. You must use @option{-fpmu-profile-generate} both
+when compiling and when linking your program. This PMU profile data
+may later be used by the compiler during optimizations as well can be
+displayed using coverage tool gcov. The params variable
+"pmu_profile_n_addresses" can be used to restrict PMU data collection
+to only this many addresses.
+
+@item -fpmu-profile-use=@var{pmuoption}
+@opindex fpmu-profile-use
+
+Enable performance monitoring unit (PMU) profiling based
+optimizations. Currently only @var{load-latency} and
+@var{branch-mispredict} are supported.
+
+@item -fcgraph-section
+@opindex fcgraph-section
+Emit call graph edge profile counts in .note.callgraph.text sections. This is
+used in conjunction with @option{-fprofile-use}. A new .note.callgraph.text
+section is created for each function. This section lists every callee and the
+number of times it is called. The params variable
+"note-cgraph-section-edge-threshold" can be used to only list edges above a
+certain threshold.
+
@item -fripa
@opindex fripa
Perform dynamic inter-procedural analysis. This is used in conjunction with
@@ -7021,6 +7076,10 @@ ignored for this comparison.
Enable printing of verbose information about dynamic inter-procedural optimizations.
This is used in conjunction with the @option{-fripa}.
+@item -fripa-no-promote-always-inline-func
+@opindex fripa-no-promote-always-inline-func
+Do not promote static functions with always inline attribute in LIPO compilation.
+
@item -fsample-profile
@itemx -fsample-profile=@var{path}
@opindex fsample-profile
@@ -7293,6 +7352,23 @@ and actually performs the optimizations based on them.
Currently the optimizations include specialization of division operation
using the knowledge about the value of the denominator.
+@item -ffvpt
+@opindex ffvpt
+If combined with @option{-fvpt and -ffvpt_functions}, it instructs the
+compiler to add a code to gather information about math library calls.
+
+With @option{-fbranch-probabilities}, it reads back the data gathered
+and actually performs the optimizations based on them.
+Currently the optimizations include specialization of function calls
+using precalculated values of common inputs.
+
+@item -ffvpt-functions=@var{ffvptfunctions}
+@opindex ffvpt
+This options takes a comma separated list of math functions to be
+profiled/optimized by @option{-ffvpt}. The special name ``all'' can be
+used to specify all supported math functions. Currently, exp, log,
+pow, and sqrt are supported.
+
@item -frename-registers
@opindex frename-registers
Attempt to avoid false dependencies in scheduled code by making use
@@ -7401,6 +7477,11 @@ If a guard check fails, an error message is printed and the program exits.
@opindex fstack-protector-all
Like @option{-fstack-protector} except that all functions are protected.
+NOTE: When --enable-esp this option is enabled by default
+for C, C++, ObjC, ObjC++, if neither @option{-fno-stack-protector}
+or @option{-nostdlib} or @option{-nodefaultlibs} or
+@option{-fstack-protector} are found.
+
@item -fsection-anchors
@opindex fsection-anchors
Try to reduce the number of symbolic address calculations by using
@@ -8138,6 +8219,15 @@ attributed to it, it will be assigned a weight of 0 with high
confidence. This parameter is only useful when using
@option{-fsample-profile}.
+@item max-lipo-mem
+When importing auxiliary modules during profile-use, check current
+memory consumption after parsing each auxiliary module. If it exceeds
+this limit (specified in kb), don't import any more auxiliary modules.
+Specifying a value of 0 means don't enforce this limit. This parameter
+is only useful when using @option{-fprofile-use} and @option{-fripa}.
+
+@item profile-generate-sampling-rate
+Set the sampling rate with @option{-fprofile-generate-sampling}.
@end table
@end table
@@ -8321,6 +8411,12 @@ For predictable results, you must also specify the same set of options
that were used to generate code (@option{-fpie}, @option{-fPIE},
or model suboptions) when you specify this option.
+NOTE: When --enable-esp this option is enabled by default
+for C, C++, ObjC, ObjC++, if neither @option{-fno-pie} or @option{-fno-PIE}
+or @option{-fno-pic} or @option{-fno-PIC} or @option{-nostdlib} or
+@option{-nostartfiles} or @option{-shared} or @option{-pg} or @option{-p}
+are found.
+
@item -rdynamic
@opindex rdynamic
Pass the flag @option{-export-dynamic} to the ELF linker, on targets
@@ -9354,11 +9450,6 @@ instructions, but still uses the soft-float calling conventions.
@samp{hard} allows generation of floating-point instructions
and uses FPU-specific calling conventions.
-Using @option{-mfloat-abi=hard} with VFP coprocessors is not supported.
-Use @option{-mfloat-abi=softfp} with the appropriate @option{-mfpu} option
-to allow the compiler to generate code that makes use of the hardware
-floating-point capabilities for these CPUs.
-
The default depends on the specific target configuration. Note that
the hard-float and soft-float ABIs are not link-compatible; you must
compile your entire program with the same ABI, and link with a
@@ -11342,6 +11433,9 @@ SSE2 and SSE3 instruction set support.
@item core2
Intel Core2 CPU with 64-bit extensions, MMX, SSE, SSE2, SSE3 and SSSE3
instruction set support.
+@item atom
+Intel Atom CPU with 64-bit extensions, MMX, SSE, SSE2, SSE3 and SSSE3
+instruction set support.
@item k6
AMD K6 CPU with MMX instruction set support.
@item k6-2, k6-3
@@ -11677,6 +11771,8 @@ preferred alignment to @option{-mpreferred-stack-boundary=2}.
@itemx -mno-sse4a
@itemx -msse5
@itemx -mno-sse5
+@itemx -mlwp
+@itemx -mno-lwp
@itemx -m3dnow
@itemx -mno-3dnow
@itemx -mpopcnt
@@ -11690,8 +11786,8 @@ preferred alignment to @option{-mpreferred-stack-boundary=2}.
@opindex m3dnow
@opindex mno-3dnow
These switches enable or disable the use of instructions in the MMX,
-SSE, SSE2, SSE3, SSSE3, SSE4.1, AVX, AES, PCLMUL, SSE4A, SSE5, ABM or
-3DNow!@: extended instruction sets.
+SSE, SSE2, SSE3, SSSE3, SSE4.1, AVX, AES, PCLMUL, SSE4A, SSE5, LWP,
+ABM or 3DNow!@: extended instruction sets.
These extensions are also available as built-in functions: see
@ref{X86 Built-in Functions}, for details of the functions enabled and
disabled by these switches.
@@ -11741,6 +11837,11 @@ SAHF are load and store instructions, respectively, for certain status flags.
In 64-bit mode, SAHF instruction is used to optimize @code{fmod}, @code{drem}
or @code{remainder} built-in functions: see @ref{Other Builtins} for details.
+@item -mmovbe
+@opindex mmovbe
+This option will enable GCC to use movbe instruction to implement
+@code{__builtin_bswap32} and @code{__builtin_bswap64}.
+
@item -mrecip
@opindex mrecip
This option will enable GCC to use RCPSS and RSQRTSS instructions (and their
@@ -11777,6 +11878,16 @@ when @option{-mveclibabi=acml} is used. Both @option{-ftree-vectorize} and
@option{-funsafe-math-optimizations} have to be enabled. A SVML or ACML ABI
compatible library will have to be specified at link time.
+@item -mabi=@var{name}
+@opindex mabi
+Generate code for the specified calling convention. Permissible values
+are: @samp{sysv} for the ABI used on GNU/Linux and other systems and
+@samp{ms} for the Microsoft ABI. The default is to use the Microsoft
+ABI when targeting Windows. On all other systems, the default is the
+SYSV ABI. You can control this behavior for a specific function by
+using the function attribute @samp{ms_abi}/@samp{sysv_abi}.
+@xref{Function Attributes}.
+
@item -mpush-args
@itemx -mno-push-args
@opindex mpush-args
@@ -16278,6 +16389,11 @@ used during linking.
@code{__pie__} and @code{__PIE__}. The macros have the value 1
for @option{-fpie} and 2 for @option{-fPIE}.
+NOTE: When --enable-esp this option is enabled by default
+for C, C++, ObjC, ObjC++, if neither @option{-fno-pie} or @option{-fno-PIE}
+or @option{-fno-pic} or @option{-fno-PIC} or @option{-nostdlib} or
+@option{-nostartfiles} or @option{-shared} are found.
+
@item -fno-jump-tables
@opindex fno-jump-tables
Do not use jump tables for switch statements even where it would be
diff --git a/gcc-4.4.3/gcc/doc/md.texi b/gcc-4.4.3/gcc/doc/md.texi
index cdfe379fb..6b3ca0a9d 100644
--- a/gcc-4.4.3/gcc/doc/md.texi
+++ b/gcc-4.4.3/gcc/doc/md.texi
@@ -7504,6 +7504,11 @@ be ignored for this case. The additional guard is necessary to
recognize complicated bypasses, e.g.@: when the consumer is only an address
of insn @samp{store} (not a stored value).
+If there are more one bypass with the same output and input insns, the
+chosen bypass is the first bypass with a guard in description whose
+guard function returns nonzero. If there is no such bypass, then
+bypass without the guard function is chosen.
+
@findex exclusion_set
@findex presence_set
@findex final_presence_set
diff --git a/gcc-4.4.3/gcc/doc/tm.texi b/gcc-4.4.3/gcc/doc/tm.texi
index 6168a446f..b6c3692d9 100644
--- a/gcc-4.4.3/gcc/doc/tm.texi
+++ b/gcc-4.4.3/gcc/doc/tm.texi
@@ -4341,6 +4341,18 @@ specially by the compiler and was not mentioned in the C code being
compiled.
@end defmac
+@deftypefn {Target Hook} rtx TARGET_LIBCALL_VALUE (enum machine_mode
+@var{mode}, rtx @var{fun})
+Define this hook if the back-end needs to know the name of the libcall
+function in order to determine where the result should be returned.
+
+The mode of the result is given by @var{mode} and the name of the called
+library function is given by @var{fun}. The hook should return an RTX
+representing the place where the library function result will be returned.
+
+If this hook is not defined, then LIBCALL_VALUE will be used.
+@end deftypefn
+
@defmac FUNCTION_VALUE_REGNO_P (@var{regno})
A C expression that is nonzero if @var{regno} is the number of a hard
register in which the values of called function may come back.
@@ -10687,17 +10699,18 @@ After successful simplify-got optimization, the pic_reg is useless. So a
target can use this hook to clear pic_reg.
@end deftypefn
-@deftypefn {Target Hook} rtx TARGET_LOADED_GLOBAL_VAR (rtx insn, rtx * offset_reg)
+@deftypefn {Target Hook} rtx TARGET_LOADED_GLOBAL_VAR (rtx @var{insn}, rtx * @var{offset_reg}, rtx * @var{offset_insn})
This hook is used to detect if the given @var{insn} loads a global
variable's address from GOT with the form of
@smallexample
-(set @var{address_reg} (mem (plus pic_reg @var{off})))
+(set @var{address_reg} (mem (plus pic_reg @var{offset_reg})))
@end smallexample
-If so store @var{off} into the memory pointed to by @var{offset_reg} and
-return the global variable whose address will be loaded. Otherwise return
-@code{NULL_RTX}.
+If so return the global variable whose address will be loaded and fill in
+@var{offset_insn} and @var{offset_reg}. @var{offset_reg} is set at
+@var{offset_insn} to hold the offset from GOT base to the GOT entry of the
+global variable. Otherwise return @code{NULL_RTX}.
@end deftypefn
@deftypefn {Target Hook} bool TARGET_CAN_SIMPLIFY_GOT_ACCESS (int @var{n_symbol}, int @var{n_access})
@@ -10707,10 +10720,10 @@ number of accessed symbols. If the returned value is false the GOT access
insns will not be rewritten. Otherwise we will rewrite these insns.
@end deftypefn
-@deftypefn {Target Hook} void TARGET_LOAD_GLOBAL_ADDRESS (rtx @var{symbol}, rtx @var{offset_reg}, rtx @var{address_reg}, rtx @var{load_insn})
+@deftypefn {Target Hook} void TARGET_LOAD_GLOBAL_ADDRESS (rtx @var{symbol}, rtx @var{offset_reg}, rtx @var{address_reg}, rtx @var{load_insn}, rtx @var{offset_insn})
This hook does the actual rewriting of GOT access insn @var{load_insn}.
The global variable is @var{symbol}. The global address should be loaded
-into @var{address_reg}. The register @var{offset_reg} was previously used
-to hold the offset from GOT base to the GOT entry of the global variable.
-Now it can be used as a scratch register.
+into @var{address_reg}. The register @var{offset_reg} was previously set
+in insn @var{offset_insn} to hold the offset from GOT base to the GOT
+entry of the global variable. Now it can be used as a scratch register.
@end deftypefn
diff --git a/gcc-4.4.3/gcc/dwarf2out.c b/gcc-4.4.3/gcc/dwarf2out.c
index 2f4ec13de..fd53312d9 100644
--- a/gcc-4.4.3/gcc/dwarf2out.c
+++ b/gcc-4.4.3/gcc/dwarf2out.c
@@ -14895,22 +14895,6 @@ decl_start_label (tree decl)
return fnname;
}
#endif
-
-/* Returns the DIE for a context. */
-
-static inline dw_die_ref
-get_context_die (tree context)
-{
- if (context)
- {
- /* Find die that represents this context. */
- if (TYPE_P (context))
- return force_type_die (context);
- else
- return force_decl_die (context);
- }
- return comp_unit_die;
-}
/* These routines generate the internal representation of the DIE's for
the compilation unit. Debugging information is collected by walking
@@ -16827,17 +16811,6 @@ gen_type_die_with_usage (tree type, dw_die_ref context_die,
statement. */
TREE_ASM_WRITTEN (type) = 1;
- /* Figure out the proper context for the basis type. If it is
- local to a function, use NULL for now; it will be fixed up
- in decls_for_scope. */
- if (TYPE_STUB_DECL (TREE_TYPE (type)) != NULL_TREE)
- {
- if (decl_function_context (TYPE_STUB_DECL (TREE_TYPE (type))))
- context_die = NULL;
- else
- context_die = get_context_die (TYPE_CONTEXT (TREE_TYPE (type)));
- }
-
/* For these types, all that is required is that we output a DIE (or a
set of DIEs) to represent the "basis" type. */
gen_type_die_with_usage (TREE_TYPE (type), context_die,
@@ -16905,6 +16878,15 @@ gen_type_die_with_usage (tree type, dw_die_ref context_die,
context_die = lookup_type_die (TYPE_CONTEXT (type));
need_pop = 1;
}
+ else if (TYPE_CONTEXT (type) != NULL_TREE
+ && (TREE_CODE (TYPE_CONTEXT (type)) == FUNCTION_DECL))
+ {
+ /* If this type is local to a function that hasn't been written
+ out yet, use a NULL context for now; it will be fixed up in
+ decls_for_scope. */
+ context_die = lookup_decl_die (TYPE_CONTEXT (type));
+ need_pop = 0;
+ }
else
{
context_die = declare_in_namespace (type, context_die);
@@ -17130,6 +17112,22 @@ is_redundant_typedef (const_tree decl)
return 0;
}
+/* Returns the DIE for a context. */
+
+static inline dw_die_ref
+get_context_die (tree context)
+{
+ if (context)
+ {
+ /* Find die that represents this context. */
+ if (TYPE_P (context))
+ return force_type_die (context);
+ else
+ return force_decl_die (context);
+ }
+ return comp_unit_die;
+}
+
/* Returns the DIE for decl. A DIE will always be returned. */
static dw_die_ref
@@ -17172,10 +17170,6 @@ force_decl_die (tree decl)
dwarf2out_decl (decl);
break;
- case TRANSLATION_UNIT_DECL:
- decl_die = comp_unit_die;
- break;
-
default:
gcc_unreachable ();
}
diff --git a/gcc-4.4.3/gcc/dyn-ipa.c b/gcc-4.4.3/gcc/dyn-ipa.c
index ae2bf2793..537acff61 100644
--- a/gcc-4.4.3/gcc/dyn-ipa.c
+++ b/gcc-4.4.3/gcc/dyn-ipa.c
@@ -43,7 +43,6 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#include "gcov-io.h"
struct dyn_pointer_set;
-struct dyn_vect;
#define XNEWVEC(type,ne) (type *)malloc(sizeof(type) * (ne))
#define XNEW(type) (type *)malloc(sizeof(type))
@@ -57,6 +56,7 @@ struct dyn_cgraph_node
struct dyn_pointer_set *imported_modules;
gcov_type guid;
+ gcov_type sum_in_count;
gcov_unsigned_t visited;
};
@@ -77,7 +77,7 @@ struct dyn_module_info
struct dyn_cgraph
{
- struct dyn_cgraph_node **call_graph_nodes;
+ struct dyn_pointer_set **call_graph_nodes;
struct gcov_info **modules;
/* supplement module information */
struct dyn_module_info *sup_modules;
@@ -92,7 +92,8 @@ struct dyn_pointer_set
size_t n_slots; /* n_slots = 2^log_slots */
size_t n_elements;
- const void **slots;
+ void **slots;
+ unsigned (*get_key) (const void *);
};
@@ -105,13 +106,18 @@ void __gcov_finalize_dyn_callgraph (void) ATTRIBUTE_HIDDEN;
static void gcov_dump_callgraph (gcov_type);
static void gcov_dump_cgraph_node_short (struct dyn_cgraph_node *node);
static void gcov_dump_cgraph_node (struct dyn_cgraph_node *node,
- unsigned m, unsigned f);
+ unsigned m, unsigned f, const char *n);
static void
gcov_dump_cgraph_node_dot (struct dyn_cgraph_node *node,
unsigned m, unsigned f,
+ const char *func_nm,
gcov_type cutoff_count);
static void
pointer_set_destroy (struct dyn_pointer_set *pset);
+static void **
+pointer_set_find_or_insert (struct dyn_pointer_set *pset, unsigned key);
+static struct dyn_pointer_set *
+pointer_set_create (unsigned (*get_key) (const void *));
static struct dyn_cgraph the_dyn_call_graph;
static int total_zero_count = 0;
@@ -172,7 +178,8 @@ get_cgraph_node (gcov_type func_guid)
if (func_id > the_dyn_call_graph.sup_modules[mod_id].max_func_ident)
return 0;
- return &the_dyn_call_graph.call_graph_nodes[mod_id][func_id];
+ return *(pointer_set_find_or_insert
+ (the_dyn_call_graph.call_graph_nodes[mod_id], func_id));
}
/* Return the gcov_info pointer for module with id MODULE_ID. */
@@ -185,6 +192,12 @@ get_module_info (gcov_unsigned_t module_id)
struct gcov_info *__gcov_list ATTRIBUTE_HIDDEN;
+static inline unsigned
+cgraph_node_get_key (const void *p)
+{
+ return get_intra_module_func_id (((const struct dyn_cgraph_node *) p)->guid);
+}
+
/* Initialize dynamic call graph. */
static void
@@ -217,7 +230,7 @@ init_dyn_call_graph (void)
= XNEWVEC (const struct gcov_fn_info **, num_modules);
the_dyn_call_graph.call_graph_nodes
- = XNEWVEC (struct dyn_cgraph_node *, num_modules);
+ = XNEWVEC (struct dyn_pointer_set *, num_modules);
gi_ptr = __gcov_list;
@@ -255,21 +268,20 @@ init_dyn_call_graph (void)
the_dyn_call_graph.call_graph_nodes[mod_id]
- = XNEWVEC (struct dyn_cgraph_node, max_func_ident + 1);
+ = pointer_set_create (cgraph_node_get_key);
the_dyn_call_graph.sup_modules[mod_id].max_func_ident = max_func_ident;
- for (j = 0; j < max_func_ident + 1; j++)
- init_dyn_cgraph_node (&the_dyn_call_graph.call_graph_nodes[mod_id][j], 0);
-
for (j = 0; j < gi_ptr->n_functions; j++)
{
const struct gcov_fn_info *fi_ptr
= the_dyn_call_graph.functions[mod_id][j];
-
- node = &the_dyn_call_graph.call_graph_nodes[mod_id][fi_ptr->ident];
- init_dyn_cgraph_node (node, GEN_FUNC_GLOBAL_ID (gi_ptr->mod_info->ident,
- fi_ptr->ident));
+ *(pointer_set_find_or_insert
+ (the_dyn_call_graph.call_graph_nodes[mod_id], fi_ptr->ident))
+ = node = XNEW (struct dyn_cgraph_node);
+ the_dyn_call_graph.call_graph_nodes[mod_id]->n_elements++;
+ init_dyn_cgraph_node (node, GEN_FUNC_GLOBAL_ID (gi_ptr->mod_info->ident,
+ fi_ptr->ident));
}
}
}
@@ -292,7 +304,9 @@ __gcov_finalize_dyn_callgraph (void)
struct dyn_cgraph_node *node;
struct dyn_cgraph_edge *callees, *next_callee;
fi_ptr = the_dyn_call_graph.functions[i][f_ix];
- node = &the_dyn_call_graph.call_graph_nodes[i][fi_ptr->ident];
+ node = *(pointer_set_find_or_insert
+ (the_dyn_call_graph.call_graph_nodes[i], fi_ptr->ident));
+ gcc_assert (node);
callees = node->callees;
if (!callees)
@@ -307,7 +321,7 @@ __gcov_finalize_dyn_callgraph (void)
pointer_set_destroy (node->imported_modules);
}
if (the_dyn_call_graph.call_graph_nodes[i])
- XDELETEVEC (the_dyn_call_graph.call_graph_nodes[i]);
+ pointer_set_destroy (the_dyn_call_graph.call_graph_nodes[i]);
if (the_dyn_call_graph.functions[i])
XDELETEVEC (the_dyn_call_graph.functions[i]);
/* Now delete sup modules */
@@ -486,7 +500,10 @@ gcov_build_callgraph (void)
{
struct dyn_cgraph_node *caller;
fi_ptr = the_dyn_call_graph.functions[m_ix][f_ix];
- caller = &the_dyn_call_graph.call_graph_nodes[m_ix][fi_ptr->ident];
+ caller = *(pointer_set_find_or_insert
+ (the_dyn_call_graph.call_graph_nodes[m_ix],
+ fi_ptr->ident));
+ gcc_assert (caller);
if (dcall_profile_values)
{
unsigned offset;
@@ -519,7 +536,7 @@ gcov_build_callgraph (void)
}
static inline size_t
-hash1 (const void *p, unsigned long max, unsigned long logmax)
+hash1 (unsigned p, unsigned long max, unsigned long logmax)
{
const unsigned long long A = 0x9e3779b97f4a7c16ull;
const unsigned long long shift = 64 - logmax;
@@ -527,10 +544,10 @@ hash1 (const void *p, unsigned long max, unsigned long logmax)
return ((A * (unsigned long) p) >> shift) & (max - 1);
}
-/* Allocate an empty pointer set. */
+/* Allocate an empty imported-modules set. */
static struct dyn_pointer_set *
-pointer_set_create (void)
+pointer_set_create (unsigned (*get_key) (const void *))
{
struct dyn_pointer_set *result = XNEW (struct dyn_pointer_set);
@@ -538,8 +555,10 @@ pointer_set_create (void)
result->log_slots = 8;
result->n_slots = (size_t) 1 << result->log_slots;
- result->slots = XNEWVEC (const void *, result->n_slots);
- memset (result->slots, 0, sizeof (const void *) * result->n_slots);
+ result->slots = XNEWVEC (void *, result->n_slots);
+ memset (result->slots, 0, sizeof (void *) * result->n_slots);
+ result->get_key = get_key;
+
return result;
}
@@ -548,19 +567,25 @@ pointer_set_create (void)
static void
pointer_set_destroy (struct dyn_pointer_set *pset)
{
+ size_t i;
+ for (i = 0; i < pset->n_slots; i++)
+ if (pset->slots[i])
+ XDELETE (pset->slots[i]);
XDELETEVEC (pset->slots);
XDELETE (pset);
}
-/* Subroutine of pointer_set_insert. Return the insertion slot for P into
- an empty element of SLOTS, an array of length N_SLOTS. */
+/* Subroutine of pointer_set_find_or_insert. Return the insertion slot for KEY
+ into an empty element of SLOTS, an array of length N_SLOTS. */
static inline size_t
-insert_aux (const void *p, const void **slots, size_t n_slots, size_t log_slots)
+insert_aux (unsigned key, void **slots,
+ size_t n_slots, size_t log_slots,
+ unsigned (*get_key) (const void *))
{
- size_t n = hash1 (p, n_slots, log_slots);
+ size_t n = hash1 (key, n_slots, log_slots);
while (1)
{
- if (slots[n] == p || slots[n] == 0)
+ if (slots[n] == 0 || get_key (slots[n]) == key)
return n;
else
{
@@ -571,28 +596,30 @@ insert_aux (const void *p, const void **slots, size_t n_slots, size_t log_slots)
}
}
-/* Insert P into PSET if it wasn't already there. Returns nonzero
- if it was already there. P must be nonnull. */
+/* Find slot for KEY. KEY must be nonnull. */
-static int
-pointer_set_insert (struct dyn_pointer_set *pset, const void *p)
+static void **
+pointer_set_find_or_insert (struct dyn_pointer_set *pset, unsigned key)
{
size_t n;
- /* For simplicity, expand the set even if P is already there. This can be
+ /* For simplicity, expand the set even if KEY is already there. This can be
superfluous but can happen at most once. */
if (pset->n_elements > pset->n_slots / 4)
{
size_t new_log_slots = pset->log_slots + 1;
size_t new_n_slots = pset->n_slots * 2;
- const void **new_slots = XNEWVEC (const void *, new_n_slots);
- memset (new_slots, 0, sizeof (const void*) * new_n_slots);
+ void **new_slots = XNEWVEC (void *, new_n_slots);
+ memset (new_slots, 0, sizeof (void *) * new_n_slots);
size_t i;
for (i = 0; i < pset->n_slots; ++i)
{
- const void *value = pset->slots[i];
- n = insert_aux (value, new_slots, new_n_slots, new_log_slots);
+ void *value = pset->slots[i];
+ if (!value)
+ continue;
+ n = insert_aux (pset->get_key (value), new_slots, new_n_slots,
+ new_log_slots, pset->get_key);
new_slots[n] = value;
}
@@ -602,37 +629,64 @@ pointer_set_insert (struct dyn_pointer_set *pset, const void *p)
pset->slots = new_slots;
}
- n = insert_aux (p, pset->slots, pset->n_slots, pset->log_slots);
- if (pset->slots[n])
- return 1;
-
- pset->slots[n] = p;
- ++pset->n_elements;
- return 0;
+ n = insert_aux (key, pset->slots, pset->n_slots, pset->log_slots,
+ pset->get_key);
+ return &pset->slots[n];
}
/* Pass each pointer in PSET to the function in FN, together with the fixed
- parameter DATA. If FN returns false, the iteration stops. */
+ parameters DATA1, DATA2, DATA3. If FN returns false, the iteration stops. */
static void
pointer_set_traverse (const struct dyn_pointer_set *pset,
- int (*fn) (const void *, void *), void *data)
+ int (*fn) (const void *, void *, void *, void *),
+ void *data1, void *data2, void *data3)
{
size_t i;
for (i = 0; i < pset->n_slots; ++i)
- if (pset->slots[i] && !fn (pset->slots[i], data))
+ if (pset->slots[i] && !fn (pset->slots[i], data1, data2, data3))
break;
}
-/* Callback function to propagate import module set (VALUE) from callee to
- caller (DATA). */
static int
-gcov_propagate_imp_modules (const void *value, void *data)
+imp_mod_set_insert (struct dyn_pointer_set *p, const struct gcov_info *imp_mod,
+ double wt)
{
- struct dyn_pointer_set *receiving_set
- = (struct dyn_pointer_set *) data;
+ struct dyn_imp_mod **m = (struct dyn_imp_mod **)
+ pointer_set_find_or_insert (p, imp_mod->mod_info->ident);
+ if (*m)
+ {
+ (*m)->weight += wt;
+ return 1;
+ }
+ else
+ {
+ *m = XNEW (struct dyn_imp_mod);
+ (*m)->imp_mod = imp_mod;
+ (*m)->weight = wt;
+ p->n_elements++;
+ return 0;
+ }
+}
- pointer_set_insert (receiving_set, value);
+/* Callback function to propagate import module (VALUE) from callee to
+ caller's imported-module-set (DATA1).
+ The weight is scaled by the scaling-factor (DATA2) before propagation,
+ and accumulated into DATA3. */
+static int
+gcov_propagate_imp_modules (const void *value, void *data1, void *data2,
+ void *data3)
+{
+ const struct dyn_imp_mod *m = (const struct dyn_imp_mod *) value;
+ struct dyn_pointer_set *receiving_set = (struct dyn_pointer_set *) data1;
+ double *scale = (double *) data2;
+ double *sum = (double *) data3;
+ double wt = m->weight;
+ if (scale)
+ wt *= *scale;
+ if (sum)
+ (*sum) += wt;
+ imp_mod_set_insert (receiving_set, m->imp_mod, wt);
return 1;
}
@@ -668,6 +722,7 @@ gcov_compute_cutoff_count (void)
unsigned cutoff_perc;
unsigned num_perc;
int do_dump;
+ const char *dump_str;
capacity = 100;
/* allocate an edge array */
@@ -687,7 +742,9 @@ gcov_compute_cutoff_count (void)
fi_ptr = the_dyn_call_graph.functions[m_ix][f_ix];
- node = &the_dyn_call_graph.call_graph_nodes[m_ix][fi_ptr->ident];
+ node = *(pointer_set_find_or_insert
+ (the_dyn_call_graph.call_graph_nodes[m_ix], fi_ptr->ident));
+ gcc_assert (node);
callees = node->callees;
while (callees != 0)
@@ -708,7 +765,7 @@ gcov_compute_cutoff_count (void)
/* Now sort */
qsort (edges, num_edges, sizeof (void *), sort_by_count);
-#define CUM_CUTOFF_PERCENT 95
+#define CUM_CUTOFF_PERCENT 80
#define MIN_NUM_EDGE_PERCENT 0
cutoff_str = getenv ("GCOV_DYN_CGRAPH_CUTOFF");
if (cutoff_str && strlen (cutoff_str))
@@ -736,11 +793,12 @@ gcov_compute_cutoff_count (void)
total += edges[i]->count;
cum_cutoff = (total * cutoff_perc)/100;
- do_dump = (getenv ("GCOV_DYN_CGRAPH_DUMP") != 0);
+ dump_str = getenv ("GCOV_DYN_CGRAPH_DUMP");
+ do_dump = (dump_str != 0 && strlen (dump_str));
for (i = 0; i < num_edges; i++)
{
cum += edges[i]->count;
- if (do_dump)
+ if (do_dump && dump_str[0] == '1')
fprintf (stderr, "// edge[%d] count = %.0f [%llx --> %llx]\n",
i, (double) edges[i]->count,
(long long) edges[i]->caller->guid,
@@ -752,7 +810,7 @@ gcov_compute_cutoff_count (void)
}
}
- if (do_dump)
+ if (do_dump && dump_str[0] == '1')
fprintf (stderr, "// total = %.0f cum = %.0f cum/total = %.0f%%"
" cutoff_count = %lld [total edges: %d hot edges: %d perc: %d%%]\n"
" total_zero_count_edges = %d total_insane_count_edgess = %d\n"
@@ -765,13 +823,19 @@ gcov_compute_cutoff_count (void)
return cutoff_count;
}
+static inline unsigned
+imp_mod_get_key (const void *p)
+{
+ return ((const struct dyn_imp_mod *) p)->imp_mod->mod_info->ident;
+}
+
/* Return the imported module set for NODE. */
static struct dyn_pointer_set *
gcov_get_imp_module_set (struct dyn_cgraph_node *node)
{
if (!node->imported_modules)
- node->imported_modules = pointer_set_create ();
+ node->imported_modules = pointer_set_create (imp_mod_get_key);
return node->imported_modules;
}
@@ -782,7 +846,7 @@ static struct dyn_pointer_set *
gcov_get_module_imp_module_set (struct dyn_module_info *mi)
{
if (!mi->imported_modules)
- mi->imported_modules = pointer_set_create ();
+ mi->imported_modules = pointer_set_create (imp_mod_get_key);
return mi->imported_modules;
}
@@ -790,10 +854,13 @@ gcov_get_module_imp_module_set (struct dyn_module_info *mi)
/* Callback function to mark if a module needs to be exported. */
static int
-gcov_mark_export_modules (const void *value, void *data ATTRIBUTE_UNUSED)
+gcov_mark_export_modules (const void *value,
+ void *data1 ATTRIBUTE_UNUSED,
+ void *data2 ATTRIBUTE_UNUSED,
+ void *data3 ATTRIBUTE_UNUSED)
{
const struct gcov_info *module_info
- = (const struct gcov_info *)value;
+ = ((const struct dyn_imp_mod *) value)->imp_mod;
module_info->mod_info->is_exported = 1;
return 1;
@@ -801,7 +868,7 @@ gcov_mark_export_modules (const void *value, void *data ATTRIBUTE_UNUSED)
struct gcov_import_mod_array
{
- const struct gcov_info **imported_modules;
+ const struct dyn_imp_mod **imported_modules;
struct gcov_info *importing_module;
unsigned len;
};
@@ -809,10 +876,12 @@ struct gcov_import_mod_array
/* Callback function to compute pointer set size. */
static int
-gcov_compute_pset_size (const void *value ATTRIBUTE_UNUSED,
- void *data)
+gcov_compute_mset_size (const void *value ATTRIBUTE_UNUSED,
+ void *data1,
+ void *data2 ATTRIBUTE_UNUSED,
+ void *data3 ATTRIBUTE_UNUSED)
{
- unsigned *len = (unsigned *) data;
+ unsigned *len = (unsigned *) data1;
(*len)++;
return 1;
}
@@ -820,36 +889,44 @@ gcov_compute_pset_size (const void *value ATTRIBUTE_UNUSED,
/* Callback function to collect imported modules. */
static int
-gcov_collect_imported_modules (const void *value, void *data)
+gcov_collect_imported_modules (const void *value,
+ void *data1,
+ void *data2 ATTRIBUTE_UNUSED,
+ void *data3 ATTRIBUTE_UNUSED)
{
struct gcov_import_mod_array *out_array;
- const struct gcov_info *module_info
- = (const struct gcov_info *)value;
+ const struct dyn_imp_mod *m
+ = (const struct dyn_imp_mod *) value;
- out_array = (struct gcov_import_mod_array *) data;
+ out_array = (struct gcov_import_mod_array *) data1;
- if (module_info != out_array->importing_module)
- out_array->imported_modules[out_array->len++] = module_info;
+ if (m->imp_mod != out_array->importing_module)
+ out_array->imported_modules[out_array->len++] = m;
return 1;
}
-/* Comparitor for sorting imported modules using module ids. */
+/* Comparator for sorting imported modules using weights. */
static int
-sort_by_module_id (const void *pa, const void *pb)
+sort_by_module_wt (const void *pa, const void *pb)
{
- const struct gcov_info *m_a = *(struct gcov_info * const *)pa;
- const struct gcov_info *m_b = *(struct gcov_info * const *)pb;
+ const struct dyn_imp_mod *m_a = *((const struct dyn_imp_mod * const *) pa);
+ const struct dyn_imp_mod *m_b = *((const struct dyn_imp_mod * const *) pb);
- return (int) m_a->mod_info->ident - (int) m_b->mod_info->ident;
+ /* We want to sort in descending order of weights. */
+ if (m_a->weight < m_b->weight)
+ return +1;
+ if (m_a->weight > m_b->weight)
+ return -1;
+ return get_module_idx (m_a->imp_mod) - get_module_idx (m_b->imp_mod);
}
/* Return a dynamic array of imported modules that is sorted for
the importing module MOD_INFO. The length of the array is returned
in *LEN. */
-const struct gcov_info **
+const struct dyn_imp_mod **
gcov_get_sorted_import_module_array (struct gcov_info *mod_info,
unsigned *len)
{
@@ -865,28 +942,86 @@ gcov_get_sorted_import_module_array (struct gcov_info *mod_info,
return 0;
pointer_set_traverse (sup_mod_info->imported_modules,
- gcov_compute_pset_size, &array_len);
- imp_array.imported_modules = XNEWVEC (const struct gcov_info *, array_len);
+ gcov_compute_mset_size, &array_len, 0, 0);
+ imp_array.imported_modules = XNEWVEC (const struct dyn_imp_mod *, array_len);
imp_array.len = 0;
imp_array.importing_module = mod_info;
pointer_set_traverse (sup_mod_info->imported_modules,
- gcov_collect_imported_modules, &imp_array);
+ gcov_collect_imported_modules, &imp_array, 0, 0);
*len = imp_array.len;
qsort (imp_array.imported_modules, imp_array.len,
- sizeof (void *), sort_by_module_id);
+ sizeof (void *), sort_by_module_wt);
return imp_array.imported_modules;
}
/* Compute modules that are needed for NODE (for cross module inlining).
- CUTTOFF_COUNT is the call graph edge count cutoff value. */
+ CUTTOFF_COUNT is the call graph edge count cutoff value.
+ IMPORT_SCALE is the scaling-factor (percent) by which to scale the
+ weights of imported modules of a callee before propagating them to
+ the caller, if the callee and caller are in different modules.
+
+ Each imported module is assigned a weight that corresponds to the
+ expected benefit due to cross-module inlining. When the imported modules
+ are written out, they are sorted with highest weight first.
+
+ The following example illustrates how the weight is computed:
+
+ Suppose we are processing call-graph node A. It calls function B 50 times,
+ which calls function C 1000 times, and function E 800 times. Lets say B has
+ another in-edge from function D, with edge-count of 50. Say all the
+ functions are in separate modules (modules a, b, c, d, e, respectively):
+
+ D
+ |
+ | 50
+ |
+ 50 v 1000
+ A --------> B ----------> C
+ |
+ | 800
+ |
+ v
+ E
+
+ Nodes are processed in depth-first order, so when processing A, we first
+ process B. For node B, we are going to add module c to the imported-module
+ set, with weight 1000 (edge-count), and module e with weight 800.
+ Coming back to A, we are going to add the imported-module-set of B to A,
+ after doing some scaling.
+ The first scaling factor comes from the fact that A calls B 50 times, but B
+ has in-edge-count total of 100. So this scaling factor is 50/100 = 0.5
+ The second scaling factor is that since B is in a different module than A,
+ we want to slightly downgrade imported modules of B, before adding to the
+ imported-modules set of A. This scaling factor has a default value of 50%
+ (can be set via env variable GCOV_DYN_IMPORT_SCALE).
+ So we end up adding modules c and e to the imported-set of A, with weights
+ 0.5*0.5*1000=250 and 0.5*0.5*800=200, respectively.
+
+ Next, we have to add module b itself to A. The weight is computed as the
+ edge-count plus the sum of scaled-weights of all modules in the
+ imported-module set of B, i.e., 50 + 250 + 200 = 500.
+
+ In computing the weight of module b, we add the sum of scaled-weights of
+ imported modules of b, because it doesn't make sense to import c, e in
+ module a, until module b is imported. */
static void
gcov_process_cgraph_node (struct dyn_cgraph_node *node,
- gcov_type cutoff_count)
+ gcov_type cutoff_count,
+ unsigned import_scale)
{
unsigned mod_id;
struct dyn_cgraph_edge *callees;
+ struct dyn_cgraph_edge *callers;
node->visited = 1;
+ node->sum_in_count = 0;
+
+ callers = node->callers;
+ while (callers)
+ {
+ node->sum_in_count += callers->count;
+ callers = callers->next_caller;
+ }
callees = node->callees;
mod_id = get_module_idx_from_func_glob_uid (node->guid);
@@ -895,7 +1030,8 @@ gcov_process_cgraph_node (struct dyn_cgraph_node *node,
{
if (!callees->callee->visited)
gcov_process_cgraph_node (callees->callee,
- cutoff_count);
+ cutoff_count,
+ import_scale);
callees = callees->next_callee;
}
@@ -911,16 +1047,24 @@ gcov_process_cgraph_node (struct dyn_cgraph_node *node,
callee_mod_id
= get_module_idx_from_func_glob_uid (callees->callee->guid);
+ double callee_mod_wt = (double) callees->count;
+ if (callees->callee->imported_modules)
+ {
+ double scale = ((double) callees->count) /
+ ((double) callees->callee->sum_in_count);
+ /* Reduce weight if callee is in different module. */
+ if (mod_id != callee_mod_id)
+ scale = (scale * import_scale) / 100.0;
+ pointer_set_traverse (callees->callee->imported_modules,
+ gcov_propagate_imp_modules,
+ imp_modules, &scale, &callee_mod_wt);
+ }
if (mod_id != callee_mod_id)
{
struct gcov_info *callee_mod_info
= get_module_info (callee_mod_id);
- pointer_set_insert (imp_modules, callee_mod_info);
+ imp_mod_set_insert (imp_modules, callee_mod_info, callee_mod_wt);
}
- if (callees->callee->imported_modules)
- pointer_set_traverse (callees->callee->imported_modules,
- gcov_propagate_imp_modules,
- imp_modules);
}
callees = callees->next_callee;
@@ -930,11 +1074,18 @@ gcov_process_cgraph_node (struct dyn_cgraph_node *node,
/* Compute module grouping using CUTOFF_COUNT as the hot edge
threshold. */
+#define DEFAULT_IMPORT_SCALE 100
static void
gcov_compute_module_groups (gcov_type cutoff_count)
{
unsigned m_ix;
struct gcov_info *gi_ptr;
+ const char *import_scale_str;
+ unsigned import_scale = DEFAULT_IMPORT_SCALE;
+
+ import_scale_str = getenv ("GCOV_DYN_IMPORT_SCALE");
+ if (import_scale_str && strlen (import_scale_str))
+ import_scale = atoi (import_scale_str);
for (m_ix = 0; m_ix < the_dyn_call_graph.num_modules; m_ix++)
{
@@ -948,11 +1099,13 @@ gcov_compute_module_groups (gcov_type cutoff_count)
struct dyn_cgraph_node *node;
fi_ptr = the_dyn_call_graph.functions[m_ix][f_ix];
- node = &the_dyn_call_graph.call_graph_nodes[m_ix][fi_ptr->ident];
+ node = *(pointer_set_find_or_insert
+ (the_dyn_call_graph.call_graph_nodes[m_ix], fi_ptr->ident));
+ gcc_assert (node);
if (node->visited)
continue;
- gcov_process_cgraph_node (node, cutoff_count);
+ gcov_process_cgraph_node (node, cutoff_count, import_scale);
}
}
@@ -970,7 +1123,9 @@ gcov_compute_module_groups (gcov_type cutoff_count)
struct dyn_pointer_set *imp_modules;
fi_ptr = the_dyn_call_graph.functions[m_ix][f_ix];
- node = &the_dyn_call_graph.call_graph_nodes[m_ix][fi_ptr->ident];
+ node = *(pointer_set_find_or_insert
+ (the_dyn_call_graph.call_graph_nodes[m_ix], fi_ptr->ident));
+ gcc_assert (node);
if (!node->imported_modules)
continue;
@@ -984,7 +1139,7 @@ gcov_compute_module_groups (gcov_type cutoff_count)
pointer_set_traverse (node->imported_modules,
gcov_propagate_imp_modules,
- imp_modules);
+ imp_modules, 0, 0);
}
}
@@ -995,7 +1150,7 @@ gcov_compute_module_groups (gcov_type cutoff_count)
= &the_dyn_call_graph.sup_modules[m_ix];
if (mi->imported_modules)
pointer_set_traverse (mi->imported_modules,
- gcov_mark_export_modules, 0);
+ gcov_mark_export_modules, 0, 0, 0);
}
}
@@ -1023,7 +1178,7 @@ gcov_compute_random_module_groups (unsigned max_group_size)
if (mod_id == m_ix)
continue;
imp_mod_info = get_module_info (mod_id);
- if (!pointer_set_insert (imp_modules, imp_mod_info))
+ if (!imp_mod_set_insert (imp_modules, imp_mod_info, 1.0))
i++;
}
}
@@ -1035,7 +1190,7 @@ gcov_compute_random_module_groups (unsigned max_group_size)
= &the_dyn_call_graph.sup_modules[m_ix];
if (mi->imported_modules)
pointer_set_traverse (mi->imported_modules,
- gcov_mark_export_modules, 0);
+ gcov_mark_export_modules, 0, 0, 0);
}
}
@@ -1118,7 +1273,7 @@ void
gcov_write_module_infos (struct gcov_info *mod_info)
{
unsigned mod_id, imp_len = 0;
- const struct gcov_info **imp_mods;
+ const struct dyn_imp_mod **imp_mods;
mod_id = get_module_idx (mod_info);
gcov_write_module_info (mod_info, 1);
@@ -1130,7 +1285,7 @@ gcov_write_module_infos (struct gcov_info *mod_info)
for (i = 0; i < imp_len; i++)
{
- const struct gcov_info *imp_mod = imp_mods[i];
+ const struct gcov_info *imp_mod = imp_mods[i]->imp_mod;
gcov_write_module_info (imp_mod, 0);
}
free (imp_mods);
@@ -1186,7 +1341,8 @@ gcov_dump_cgraph_node_short (struct dyn_cgraph_node *node)
/* Dumper function for NODE. M is the module id and F is the function id. */
static void
-gcov_dump_cgraph_node (struct dyn_cgraph_node *node, unsigned m, unsigned f)
+gcov_dump_cgraph_node (struct dyn_cgraph_node *node, unsigned m, unsigned f,
+ const char *n)
{
unsigned mod_id, func_id;
struct gcov_info *mod_info;
@@ -1199,9 +1355,9 @@ gcov_dump_cgraph_node (struct dyn_cgraph_node *node, unsigned m, unsigned f)
mod_info = the_dyn_call_graph.modules[mod_id];
- fprintf (stderr, "NODE(%llx) module(%s) func(%x)\n",
+ fprintf (stderr, "NODE(%llx) module(%s):%s(%x)\n",
(long long) node->guid,
- mod_info->mod_info->source_filename, f);
+ mod_info->mod_info->source_filename, n, f);
/* Now dump callers. */
callers = node->callers;
@@ -1228,13 +1384,12 @@ gcov_dump_cgraph_node (struct dyn_cgraph_node *node, unsigned m, unsigned f)
/* Dumper function for NODE. M is the module id and F is the function id. */
static void
-gcov_dump_cgraph_node_dot (struct dyn_cgraph_node *node,
- unsigned m, unsigned f,
- gcov_type cutoff_count)
+gcov_dump_cgraph_node_dot (struct dyn_cgraph_node *node, unsigned m,
+ unsigned f, const char * n, gcov_type cutoff_count)
{
unsigned mod_id, func_id, imp_len = 0, i;
struct gcov_info *mod_info;
- const struct gcov_info **imp_mods;
+ const struct dyn_imp_mod **imp_mods;
struct dyn_cgraph_edge *callees;
mod_id = get_module_idx_from_func_glob_uid (node->guid);
@@ -1243,15 +1398,15 @@ gcov_dump_cgraph_node_dot (struct dyn_cgraph_node *node,
mod_info = the_dyn_call_graph.modules[mod_id];
- fprintf (stderr, "NODE_%llx[label=\"MODULE\\n(%s)\\n FUNC(%x)\\n",
- (long long) node->guid, mod_info->mod_info->source_filename, f);
+ fprintf (stderr, "NODE_%llx[label=\"MODULE\\n(%s)\\n %s(%x)\\n",
+ (long long) node->guid, mod_info->mod_info->source_filename, n, f);
imp_mods = gcov_get_sorted_import_module_array (mod_info, &imp_len);
fprintf (stderr, "IMPORTS:\\n");
if (imp_mods)
{
for (i = 0; i < imp_len; i++)
- fprintf (stderr, "%s\\n", imp_mods[i]->mod_info->source_filename);
+ fprintf (stderr, "%s\\n", imp_mods[i]->imp_mod->mod_info->source_filename);
fprintf (stderr, "\"]\n");
free (imp_mods);
}
@@ -1302,17 +1457,19 @@ gcov_dump_callgraph (gcov_type cutoff_count)
struct dyn_cgraph_node *node;
fi_ptr = the_dyn_call_graph.functions[m_ix][f_ix];
- node = &the_dyn_call_graph.call_graph_nodes[m_ix][fi_ptr->ident];
+ node = *(pointer_set_find_or_insert
+ (the_dyn_call_graph.call_graph_nodes[m_ix], fi_ptr->ident));
+ gcc_assert (node);
/* skip dead functions */
if (!node->callees && !node->callers)
continue;
if (dyn_cgraph_dump[0] == '1')
- gcov_dump_cgraph_node (node, m_ix, fi_ptr->ident);
+ gcov_dump_cgraph_node (node, m_ix, fi_ptr->ident, fi_ptr->name);
else
gcov_dump_cgraph_node_dot (node, m_ix, fi_ptr->ident,
- cutoff_count);
+ fi_ptr->name, cutoff_count);
}
}
fprintf (stderr,"}\n");
diff --git a/gcc-4.4.3/gcc/esp.h b/gcc-4.4.3/gcc/esp.h
new file mode 100644
index 000000000..db2135b72
--- /dev/null
+++ b/gcc-4.4.3/gcc/esp.h
@@ -0,0 +1,145 @@
+/* License terms see GNU GENERAL PUBLIC LICENSE Version 3.
+ * Version 20100527.1
+ * Magnus Granberg (Zorry) <zorry@gentoo.org> */
+#ifndef GCC_ESP_H
+#define GCC_ESP_H
+
+/* This file will add -fstack-protector-all, -fPIE, -pie and -z now
+ as default if the defines and the spec allow it.
+ Added a hack for gcc-specs-* in toolchain-funcs.eclass and _filter-hardened in flag-o-matic.eclass
+ to support older hardened GCC patches and we don't need to change the code on gcc-specs-* and _filter-hardened.
+ This will add some unsupported upstream commands options as -nopie and -nonow.
+ -D__KERNEL__ is added so we don't have -fPIE, -pie and -fstack-protector-all when building kernels.
+ ESP_CC1_SPEC is added to CC1_SPEC.
+ ESP_CC1_STRICT_OVERFLOW_SPEC is added so we don't disable the strict-overflow check.
+ ESP_LINK_PIE_CHECK_SPEC check for -pie, -p, -pg, -profile and -static.
+ ENABLE_CRTBEGINTS add support for crtbeginTS.o, build -static with -fPIE or -fpie.
+*/
+#ifdef ENABLE_ESP
+
+ /* Hack to support gcc-specs-* in toolchain-funcs.eclass and _filter-hardened in flag-o-matic.eclass */
+ #define ESP_CC1_SPEC " %(esp_cc1_ssp) %(esp_cc1_pie) %(esp_cc1_strict_overflow)"
+ #if defined ( EFAULT_SSP ) || defined ( EFAULT_PIE_SSP )
+ #define ESP_CC1_SSP_SPEC "%{!fno-stack-protector: %{!fno-stack-protector-all: }}"
+ #else
+ #define ESP_CC1_SSP_SPEC ""
+ #endif
+ #if defined ( EFAULT_PIE ) || defined ( EFAULT_PIE_SSP )
+ #define ESP_CC1_PIE_SPEC "%{!nopie: }"
+ #else
+ #define ESP_CC1_PIE_SPEC ""
+ #endif
+ #define ESP_CC1_STRICT_OVERFLOW_SPEC "%{!fstrict-overflow:%{!fno-strict-overflow: -fno-strict-overflow}}"
+
+ /* ESP_LINK_SPEC is added to LINK_PIE_SPEC if esp is enable
+ -z now will be added if we don't have -vanilla spec. We do a -pie incompatible check
+ Don't remove the specs in the end */
+ #define ESP_LINK_SPEC "%(esp_link_now) %(esp_link_pie_check) "
+ #define ESP_LINK_NOW_SPEC "%{!nonow:-z now}"
+
+ /* We use ESP_COMMAND_OPTIONS_SPEC to add pie command-line options. */
+ #define ESP_COMMAND_OPTIONS_SPEC "%{!D__KERNEL__:%{!nopie:%(esp_options_pie) %(esp_link_pie)}}"
+
+ /* ESP_OPTIONS_SPEC is added to the compiler spec in gcc/gcc.c */
+ #define ESP_OPTIONS_SPEC "%(esp_options_ssp)"
+
+ /* ESP_CPP_OPTIONS_SPEC is added to the cpp_options spec in gcc/gcc.c
+ For precompiling headers. */
+ #define ESP_CPP_OPTIONS_SPEC "%(esp_options_ssp)"
+
+ /* This will add -fstack-protector-all if we don't have -nostdlib -nodefaultlibs -fno-stack-protector -fstack-protector
+ -fstack-protector-all and we have EFAULT_SSP or EFAULT_PIE_SSP defined. */
+ #if defined ( EFAULT_SSP ) || defined ( EFAULT_PIE_SSP )
+ #define ESP_OPTIONS_SSP_SPEC \
+ "%{!D__KERNEL__:%{!nostdlib:%{!nodefaultlibs: %{!fno-stack-protector: \
+ %{!fstack-protector:%{!fstack-protector-all:-fstack-protector-all}}}}}}"
+ #else
+ #define ESP_OPTIONS_SSP_SPEC ""
+ #endif
+
+ /* If EFAULT_PIE or EFAULT_PIE_SSP is defined we will add -fPIE -pie */
+ #if defined ( EFAULT_PIE ) || defined ( EFAULT_PIE_SSP )
+
+ /* This will add -fPIE if we don't have -pie -fpic -fPIC -fpie -fPIE -fno-pic -fno-PIC -fno-pie -fno-PIE -shared -static
+ -nostdlib -nostartfiles. */
+ /* With ENABLE_CRTBEGINTS we don't need to check for -static */
+ #ifdef ENABLE_CRTBEGINTS
+ #define ESP_OPTIONS_PIE_SPEC \
+ "%{!pie: %{!fpic:%{!fPIC:%{!fpie:%{!fPIE: %{!fno-pic:%{!fno-PIC:%{!fno-pie:%{!fno-PIE: \
+ %{!shared: %{!nostdlib: %{!nostartfiles:-fPIE}} } }}}} }}}} }"
+ #else
+ #define ESP_OPTIONS_PIE_SPEC \
+ "%{!pie: %{!fpic:%{!fPIC:%{!fpie:%{!fPIE: %{!fno-pic:%{!fno-PIC:%{!fno-pie:%{!fno-PIE: \
+ %{!shared: %{!static: %{!nostdlib: %{!nostartfiles:-fPIE}} } }}}} }}}} }}"
+ #endif
+
+ /* This will add -pie if we don't have -pie -A -fno-pic -fno-PIC -fno-pie -fno-PIE -shared -static -r -nostdlib
+ -nostartfiles */
+ /* With ENABLE_CRTBEGINTS we don't need to check for -static
+ and we add -pie only to get the start and endfiles. -pie will not go to the linker. */
+ #ifdef ENABLE_CRTBEGINTS
+ #define ESP_LINK_PIE_SPEC \
+ "%{!pie:%{!A:%{!fno-pie:%{!fno-PIE:%{!fno-pic:%{!fno-PIC:%{!shared:%{!r: \
+ %{!nostdlib:%{!nostartfiles:-pie}}}}}}}}}}"
+ #else
+ #define ESP_LINK_PIE_SPEC \
+ "%{!pie:%{!A:%{!fno-pie:%{!fno-PIE:%{!fno-pic:%{!fno-PIC:%{!shared:%{!static:%{!r: \
+ %{!nostdlib:%{!nostartfiles:-pie}}}}}}}}}}}"
+ #endif
+
+ /* This will check if -pie is set when (-static) -pg -p -profile. If set it will make gcc print out
+ "-pie and (static)|pg|p|profile are incompatible when linking" */
+ /* With ENABLE_CRTBEGINTS we don't need to check for -static */
+ #ifdef ENABLE_CRTBEGINTS
+ #define ESP_LINK_PIE_CHECK_SPEC \
+ "%{pie:%{pg|p|profile:%e-pie and -pg|p|profile are incompatible when linking}}"
+ #else
+ #define ESP_LINK_PIE_CHECK_SPEC \
+ "%{pie:%{static|pg|p|profile:%e-pie and -static|pg|p|profile are incompatible when linking}}"
+ #endif
+
+ /* We don't pass -pie to the linker when -static. */
+ #ifdef ENABLE_CRTBEGINTS
+ #define LINK_PIE_SPEC "%{!static:%{pie:-pie}} %(esp_link)"
+ #else
+ #define LINK_PIE_SPEC "%{pie:-pie} %(esp_link)"
+ #endif
+
+ #else
+ #define ESP_OPTIONS_PIE_SPEC ""
+ #define ESP_LINK_PIE_CHECK_SPEC ""
+ #define ESP_LINK_PIE_SPEC ""
+ #define LINK_PIE_SPEC "%{pie:-pie} %(esp_link)"
+ #endif
+
+ /* We add extra spec name's to the EXTRA_SPECS list */
+ #define ESP_EXTRA_SPECS \
+ { "esp_cc1", ESP_CC1_SPEC }, \
+ { "esp_cc1_pie", ESP_CC1_PIE_SPEC }, \
+ { "esp_cc1_ssp", ESP_CC1_SSP_SPEC }, \
+ { "esp_cc1_strict_overflow", ESP_CC1_STRICT_OVERFLOW_SPEC }, \
+ { "esp_link", ESP_LINK_SPEC }, \
+ { "esp_link_now", ESP_LINK_NOW_SPEC }, \
+ { "esp_link_pie", ESP_LINK_PIE_SPEC }, \
+ { "esp_link_pie_check", ESP_LINK_PIE_CHECK_SPEC }, \
+ { "esp_command_options", ESP_COMMAND_OPTIONS_SPEC }, \
+ { "esp_cpp_options", ESP_CPP_OPTIONS_SPEC }, \
+ { "esp_options", ESP_OPTIONS_SPEC }, \
+ { "esp_options_pie", ESP_OPTIONS_PIE_SPEC }, \
+ { "esp_options_ssp", ESP_OPTIONS_SSP_SPEC }
+
+ static const char *esp_command_options_spec = ESP_COMMAND_OPTIONS_SPEC;
+ static const char *cc1_spec = CC1_SPEC ESP_CC1_SPEC;
+
+#else /* If not ESP_ENABLE defined do this. */
+
+ #define ESP_OPTIONS_SPEC ""
+ #define ESP_CPP_OPTIONS_SPEC ""
+
+ /* We add extra spec name's to the EXTRA_SPECS list */
+ #define ESP_EXTRA_SPECS \
+ { "esp_options", ESP_OPTIONS_SPEC }, \
+ { "esp_cpp_options", ESP_CPP_OPTIONS_SPEC }
+
+#endif
+#endif /* End GCC_ESP_H */
diff --git a/gcc-4.4.3/gcc/explow.c b/gcc-4.4.3/gcc/explow.c
index c9bf675d3..d43aad00d 100644
--- a/gcc-4.4.3/gcc/explow.c
+++ b/gcc-4.4.3/gcc/explow.c
@@ -1491,9 +1491,9 @@ hard_function_value (const_tree valtype, const_tree func, const_tree fntype,
in which a scalar value of mode MODE was returned by a library call. */
rtx
-hard_libcall_value (enum machine_mode mode)
+hard_libcall_value (enum machine_mode mode, rtx fun)
{
- return LIBCALL_VALUE (mode);
+ return targetm.calls.libcall_value (mode, fun);
}
/* Look up the tree code for a given rtx code
diff --git a/gcc-4.4.3/gcc/expr.h b/gcc-4.4.3/gcc/expr.h
index 216de87fe..a89d4f916 100644
--- a/gcc-4.4.3/gcc/expr.h
+++ b/gcc-4.4.3/gcc/expr.h
@@ -757,7 +757,7 @@ extern void probe_stack_range (HOST_WIDE_INT, rtx);
/* Return an rtx that refers to the value returned by a library call
in its original home. This becomes invalid if any more code is emitted. */
-extern rtx hard_libcall_value (enum machine_mode);
+extern rtx hard_libcall_value (enum machine_mode, rtx);
/* Return the mode desired by operand N of a particular bitfield
insert/extract insn, or MAX_MACHINE_MODE if no such insn is
diff --git a/gcc-4.4.3/gcc/final.c b/gcc-4.4.3/gcc/final.c
index dc9a6d818..2c0be960d 100644
--- a/gcc-4.4.3/gcc/final.c
+++ b/gcc-4.4.3/gcc/final.c
@@ -1649,6 +1649,58 @@ final_end_function (void)
#endif
}
+
+static basic_block *start_to_bb = NULL;
+static basic_block *end_to_bb = NULL;
+static int bb_map_size = 0;
+static int bb_seq = 0;
+
+/* Dumper helper for basic block information. FILE is the assembly
+ output file, and INSN is the instruction being emitted. */
+
+static void
+dump_basic_block_info (FILE *file, rtx insn)
+{
+ basic_block bb;
+
+ if (!flag_debug_asm)
+ return;
+
+ if (INSN_UID (insn) < bb_map_size
+ && (bb = start_to_bb[INSN_UID (insn)]) != NULL)
+ {
+ edge e;
+ edge_iterator ei;
+
+ fprintf (file, "# BLOCK %d", bb->index);
+ if (bb->frequency)
+ fprintf (file, " freq:%d", bb->frequency);
+ if (bb->count)
+ fprintf (file, " count:" HOST_WIDEST_INT_PRINT_DEC,
+ bb->count);
+ fprintf (file, " seq:%d", bb_seq++);
+ fprintf (file, "\n# PRED:");
+ FOR_EACH_EDGE (e, ei, bb->preds)
+ {
+ dump_edge_info (file, e, 0);
+ }
+ fprintf (file, "\n");
+ }
+ if (INSN_UID (insn) < bb_map_size
+ && (bb = end_to_bb[INSN_UID (insn)]) != NULL)
+ {
+ edge e;
+ edge_iterator ei;
+
+ fprintf (asm_out_file, "# SUCC:");
+ FOR_EACH_EDGE (e, ei, bb->succs)
+ {
+ dump_edge_info (asm_out_file, e, 1);
+ }
+ fprintf (file, "\n");
+ }
+}
+
/* Output assembler code for some insns: all or part of a function.
For description of args, see `final_start_function', above. */
@@ -1683,6 +1735,21 @@ final (rtx first, FILE *file, int optimize)
CC_STATUS_INIT;
+ if (flag_debug_asm)
+ {
+ basic_block bb;
+
+ bb_map_size = get_max_uid () + 1;
+ start_to_bb = XCNEWVEC (basic_block, bb_map_size);
+ end_to_bb = XCNEWVEC (basic_block, bb_map_size);
+
+ FOR_EACH_BB_REVERSE (bb)
+ {
+ start_to_bb[INSN_UID (BB_HEAD (bb))] = bb;
+ end_to_bb[INSN_UID (BB_END (bb))] = bb;
+ }
+ }
+
/* Output the insns. */
for (insn = first; insn;)
{
@@ -1698,8 +1765,19 @@ final (rtx first, FILE *file, int optimize)
insn_current_address = INSN_ADDRESSES (INSN_UID (insn));
#endif /* HAVE_ATTR_length */
+ dump_basic_block_info (file, insn);
insn = final_scan_insn (insn, file, optimize, 0, &seen);
}
+
+ if (flag_debug_asm)
+ {
+ free (start_to_bb);
+ free (end_to_bb);
+ start_to_bb = NULL;
+ end_to_bb = NULL;
+ bb_map_size = 0;
+ bb_seq = 0;
+ }
}
const char *
@@ -1834,10 +1912,6 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
targetm.asm_out.unwind_emit (asm_out_file, insn);
#endif
- if (flag_debug_asm)
- fprintf (asm_out_file, "\t%s basic block %d\n",
- ASM_COMMENT_START, NOTE_BASIC_BLOCK (insn)->index);
-
if ((*seen & (SEEN_EMITTED | SEEN_BB)) == SEEN_BB)
{
*seen |= SEEN_EMITTED;
@@ -4203,13 +4277,35 @@ debug_free_queue (void)
symbol_queue_size = 0;
}
}
-
+
+/* List the call graph profiled edges in the ".note.callgraph.text" section. */
+static void
+cgraph_get_profiles (void)
+{
+ struct cgraph_node *node = cgraph_node (current_function_decl);
+ struct cgraph_edge *e;
+ struct cgraph_node *callee;
+
+ for (e = node->callees; e != NULL; e = e->next_callee)
+ {
+ if (e->count <= PARAM_VALUE (PARAM_NOTE_CGRAPH_SECTION_EDGE_THRESHOLD))
+ continue;
+ callee = e->callee;
+ fprintf (asm_out_file, "\t.string \"%s\"\n",
+ IDENTIFIER_POINTER (decl_assembler_name (callee->decl)));
+ fprintf (asm_out_file, "\t.string \"" HOST_WIDEST_INT_PRINT_DEC "\"\n",
+ e->count);
+ }
+}
+
/* Turn the RTL into assembly. */
static unsigned int
rest_of_handle_final (void)
{
rtx x;
const char *fnname;
+ char *profile_fnname;
+ unsigned int flags;
/* Get the function's name, as described by its RTL. This may be
different from the DECL_NAME name used in the source file. */
@@ -4274,6 +4370,22 @@ rest_of_handle_final (void)
targetm.asm_out.destructor (XEXP (DECL_RTL (current_function_decl), 0),
decl_fini_priority_lookup
(current_function_decl));
+
+ /* With -fcgraph-section, add ".note.callgraph.text" section for storing
+ profiling information. */
+ if (flag_cgraph_section
+ && flag_profile_use
+ && cgraph_node (current_function_decl) != NULL)
+ {
+ flags = SECTION_NOTYPE;
+ profile_fnname = (char *)xmalloc(strlen(".note.callgraph.text.")
+ + strlen(fnname) + 1);
+ sprintf(profile_fnname, ".note.callgraph.text.%s", fnname);
+ switch_to_section(get_section(profile_fnname, flags, NULL));
+ fprintf (asm_out_file, "\t.string \"Function %s\"\n", fnname);
+ cgraph_get_profiles ();
+ free (profile_fnname);
+ }
return 0;
}
diff --git a/gcc-4.4.3/gcc/flags.h b/gcc-4.4.3/gcc/flags.h
index 57ea8c0c4..9507d2b94 100644
--- a/gcc-4.4.3/gcc/flags.h
+++ b/gcc-4.4.3/gcc/flags.h
@@ -399,6 +399,16 @@ enum warn_strict_overflow_code
WARN_STRICT_OVERFLOW_MAGNITUDE = 5
};
+/* Math functions that the ffvpt-pass will profile and optimize. */
+struct ffvpt_options_s
+{
+ bool exp_set;
+ bool log_set;
+ bool pow_set;
+ bool sqrt_set;
+};
+extern struct ffvpt_options_s ffvpt_options;
+
/* Whether to emit an overflow warning whose code is C. */
#define issue_strict_overflow_warning(c) (warn_strict_overflow >= (int) (c))
diff --git a/gcc-4.4.3/gcc/fold-const.c b/gcc-4.4.3/gcc/fold-const.c
index fd4debd36..e1931e66b 100644
--- a/gcc-4.4.3/gcc/fold-const.c
+++ b/gcc-4.4.3/gcc/fold-const.c
@@ -7901,46 +7901,11 @@ native_interpret_int (tree type, const unsigned char *ptr, int len)
static tree
native_interpret_real (tree type, const unsigned char *ptr, int len)
{
- enum machine_mode mode = TYPE_MODE (type);
- int total_bytes = GET_MODE_SIZE (mode);
- int byte, offset, word, words, bitpos;
- unsigned char value;
- /* There are always 32 bits in each long, no matter the size of
- the hosts long. We handle floating point representations with
- up to 192 bits. */
REAL_VALUE_TYPE r;
- long tmp[6];
-
- total_bytes = GET_MODE_SIZE (TYPE_MODE (type));
- if (total_bytes > len || total_bytes > 24)
+ if (!real_from_native (type, ptr, len, &r))
return NULL_TREE;
- words = (32 / BITS_PER_UNIT) / UNITS_PER_WORD;
-
- memset (tmp, 0, sizeof (tmp));
- for (bitpos = 0; bitpos < total_bytes * BITS_PER_UNIT;
- bitpos += BITS_PER_UNIT)
- {
- byte = (bitpos / BITS_PER_UNIT) & 3;
- if (UNITS_PER_WORD < 4)
- {
- word = byte / UNITS_PER_WORD;
- if (WORDS_BIG_ENDIAN)
- word = (words - 1) - word;
- offset = word * UNITS_PER_WORD;
- if (BYTES_BIG_ENDIAN)
- offset += (UNITS_PER_WORD - 1) - (byte % UNITS_PER_WORD);
- else
- offset += byte % UNITS_PER_WORD;
- }
- else
- offset = BYTES_BIG_ENDIAN ? 3 - byte : byte;
- value = ptr[offset + ((bitpos / BITS_PER_UNIT) & ~3)];
-
- tmp[bitpos / 32] |= (unsigned long)value << (bitpos & 31);
- }
-
- real_from_target (&r, tmp, mode);
- return build_real (type, r);
+ else
+ return build_real (type, r);
}
diff --git a/gcc-4.4.3/gcc/fortran/module.c b/gcc-4.4.3/gcc/fortran/module.c
index b5c522f93..5a2b6d1ea 100644
--- a/gcc-4.4.3/gcc/fortran/module.c
+++ b/gcc-4.4.3/gcc/fortran/module.c
@@ -3319,7 +3319,7 @@ mio_f2k_derived (gfc_namespace *f2k)
f2k->finalizers = NULL;
while (peek_atom () != ATOM_RPAREN)
{
- gfc_finalizer *cur;
+ gfc_finalizer *cur = NULL;
mio_finalizer (&cur);
cur->next = f2k->finalizers;
f2k->finalizers = cur;
diff --git a/gcc-4.4.3/gcc/function.h b/gcc-4.4.3/gcc/function.h
index 2e2542b13..967846707 100644
--- a/gcc-4.4.3/gcc/function.h
+++ b/gcc-4.4.3/gcc/function.h
@@ -521,6 +521,10 @@ struct function GTY(())
/* Used types hash table. */
htab_t GTY ((param_is (union tree_node))) used_types_hash;
+ /* Map between variables synthesized in stack_overlay to the original
+ variables. Used in RTL emission.*/
+ htab_t GTY ((param_is (struct overlay_decl_mapping))) union_decl_list_map;
+
/* Last statement uid. */
int last_stmt_uid;
diff --git a/gcc-4.4.3/gcc/gcc.c b/gcc-4.4.3/gcc/gcc.c
index f22ef3385..3ce244cdf 100644
--- a/gcc-4.4.3/gcc/gcc.c
+++ b/gcc-4.4.3/gcc/gcc.c
@@ -83,6 +83,7 @@ compilation is specified by a string called a "spec". */
#include "gcc.h"
#include "flags.h"
#include "opts.h"
+#include "esp.h" /* for --enable-esp support */
/* By default there is no special suffix for target executables. */
/* FIXME: when autoconf is fixed, remove the host check - dj */
@@ -727,6 +728,10 @@ proper position among the other output files. */
# endif
#endif
+/* Google-local http://b/2739909 */
+#ifndef LINK_RPATH_SPEC
+# define LINK_RPATH_SPEC ""
+#endif
/* -u* was put back because both BSD and SysV seem to support it. */
/* %{static:} simply prevents an error message if the target machine
@@ -738,6 +743,7 @@ proper position among the other output files. */
#define LINK_COMMAND_SPEC "\
%{!fsyntax-only:%{!c:%{!M:%{!MM:%{!E:%{!S:\
%(linker) %l " LINK_PIE_SPEC \
+ LINK_RPATH_SPEC \
"%{fuse-ld=gold:%{fuse-ld=bfd:%e-fuse-ld=gold and -fuse-ld=bfd may not be used together}} \
%{fuse-ld=gold:-use-gold} \
%{fuse-ld=bfd:-use-ld}" \
@@ -745,7 +751,7 @@ proper position among the other output files. */
%{s} %{t} %{u*} %{x} %{z} %{Z} %{!A:%{!nostdlib:%{!nostartfiles:%S}}}\
%{static:} %{L*} %(mfwrap) %(link_libgcc) %o\
%{fopenmp|ftree-parallelize-loops=*:%:include(libgomp.spec)%(link_gomp)} %(mflib)\
- %{fprofile-arcs|fprofile-generate*|coverage:-lgcov}\
+ %{fprofile-arcs|fprofile-generate*|fpmu-profile-generate*|coverage:-lgcov}\
%{!nostdlib:%{!nodefaultlibs:%(link_ssp) %(link_gcc_c_sequence)}}\
%{!A:%{!nostdlib:%{!nostartfiles:%E}}} %{T*} }}}}}}"
#endif
@@ -773,7 +779,9 @@ proper position among the other output files. */
static const char *asm_debug;
static const char *cpp_spec = CPP_SPEC;
+#ifndef ENABLE_ESP
static const char *cc1_spec = CC1_SPEC;
+#endif
static const char *cc1plus_spec = CC1PLUS_SPEC;
static const char *link_gcc_c_sequence_spec = LINK_GCC_C_SEQUENCE_SPEC;
static const char *link_ssp_spec = LINK_SSP_SPEC;
@@ -832,7 +840,7 @@ static const char *cpp_unique_options =
static const char *cpp_options =
"%(cpp_unique_options) %1 %{m*} %{std*&ansi&trigraphs} %{W*&pedantic*} %{w}\
%{f*} %{g*:%{!g0:%{g*} %{!fno-working-directory:-fworking-directory}}} %{O*}\
- %{undef} %{save-temps:-fpch-preprocess}";
+ %{undef} %{save-temps:-fpch-preprocess} %(esp_cpp_options)";
/* This contains cpp options which are not passed when the preprocessor
output will be used by another program. */
@@ -1014,15 +1022,15 @@ static const struct compiler default_compilers[] =
%{save-temps|traditional-cpp|no-integrated-cpp:%(trad_capable_cpp) \
%(cpp_options) -o %{save-temps:%b.i} %{!save-temps:%g.i} \n\
cc1 -fpreprocessed %{save-temps:%b.i} %{!save-temps:%g.i} \
- %(cc1_options)}\
+ %(cc1_options) %(espf_options)}\
%{!save-temps:%{!traditional-cpp:%{!no-integrated-cpp:\
- cc1 %(cpp_unique_options) %(cc1_options)}}}\
+ cc1 %(cpp_unique_options) %(cc1_options) %(esp_options)}}}\
%{!fsyntax-only:%(invoke_as)}} \
%{combine:\
%{save-temps|traditional-cpp|no-integrated-cpp:%(trad_capable_cpp) \
%(cpp_options) -o %{save-temps:%b.i} %{!save-temps:%g.i}}\
%{!save-temps:%{!traditional-cpp:%{!no-integrated-cpp:\
- cc1 %(cpp_unique_options) %(cc1_options)}}\
+ cc1 %(cpp_unique_options) %(cc1_options) %(esp_options)}}\
%{!fsyntax-only:%(invoke_as)}}}}}}", 0, 1, 1},
{"-",
"%{!E:%e-E or -x required when input is from standard input}\
@@ -1045,7 +1053,7 @@ static const struct compiler default_compilers[] =
%W{o*:--output-pch=%*}%V}}}}}}", 0, 0, 0},
{".i", "@cpp-output", 0, 1, 0},
{"@cpp-output",
- "%{!M:%{!MM:%{!E:cc1 -fpreprocessed %i %(cc1_options) %{!fsyntax-only:%(invoke_as)}}}}", 0, 1, 0},
+ "%{!M:%{!MM:%{!E:cc1 -fpreprocessed %i %(cc1_options) %(esp_options) %{!fsyntax-only:%(invoke_as)}}}}", 0, 1, 0},
{".s", "@assembler", 0, 1, 0},
{"@assembler",
"%{!M:%{!MM:%{!E:%{!S:as %(asm_debug) %(asm_options) %i %A }}}}", 0, 1, 0},
@@ -1634,18 +1642,23 @@ static struct spec_list static_specs[] =
INIT_STATIC_SPEC ("sysroot_hdrs_suffix_spec", &sysroot_hdrs_suffix_spec),
};
-#ifdef EXTRA_SPECS /* additional specs needed */
+/* EXTRA_SPECS needs to be defined */
+#ifndef EXTRA_SPECS
+#define EXTRA_SPECS
+#endif
+
+/* EXTRA_SPECS and ESP_EXTRA_SPECS add additional specs */
/* Structure to keep track of just the first two args of a spec_list.
- That is all that the EXTRA_SPECS macro gives us. */
+ That is all that the EXTRA_SPECS and ESP_EXTRA_SPECS macro gives us. */
struct spec_list_1
{
const char *const name;
const char *const ptr;
};
-static const struct spec_list_1 extra_specs_1[] = { EXTRA_SPECS };
+/* ESP_EXTRA_SPECS before EXTRA_SPECS */
+static const struct spec_list_1 extra_specs_1[] = { ESP_EXTRA_SPECS, EXTRA_SPECS };
static struct spec_list *extra_specs = (struct spec_list *) 0;
-#endif
/* List of dynamically allocates specs that have been defined so far. */
@@ -1730,7 +1743,6 @@ init_spec (void)
if (verbose_flag)
notice ("Using built-in specs.\n");
-#ifdef EXTRA_SPECS
extra_specs = XCNEWVEC (struct spec_list, ARRAY_SIZE (extra_specs_1));
for (i = ARRAY_SIZE (extra_specs_1) - 1; i >= 0; i--)
@@ -1743,7 +1755,6 @@ init_spec (void)
sl->ptr_spec = &sl->ptr;
next = sl;
}
-#endif
for (i = ARRAY_SIZE (static_specs) - 1; i >= 0; i--)
{
@@ -6536,6 +6547,12 @@ main (int argc, char **argv)
gcc_exec_prefix = concat (gcc_exec_prefix, spec_machine, dir_separator_str,
spec_version, dir_separator_str, NULL);
+#ifdef ENABLE_ESP
+ /* Process ESP_COMMAND_OPTIONS_SPEC, adding any new options to the end
+ of the command line. */
+ do_self_spec (esp_command_options_spec);
+#endif
+
/* Now we have the specs.
Set the `valid' bits for switches that match anything in any spec. */
diff --git a/gcc-4.4.3/gcc/gcov-dump.c b/gcc-4.4.3/gcc/gcov-dump.c
index 681bdbfbe..0417ab1a9 100644
--- a/gcc-4.4.3/gcc/gcov-dump.c
+++ b/gcc-4.4.3/gcc/gcov-dump.c
@@ -39,6 +39,10 @@ static void tag_lines (const char *, unsigned, unsigned);
static void tag_counters (const char *, unsigned, unsigned);
static void tag_summary (const char *, unsigned, unsigned);
static void tag_module_info (const char *, unsigned, unsigned);
+static void tag_pmu_load_latency_info (const char *, unsigned, unsigned);
+static void tag_pmu_branch_mispredict_info (const char *, unsigned, unsigned);
+static void tag_pmu_tool_header (const char *, unsigned, unsigned);
+
extern int main (int, char **);
typedef struct tag_format
@@ -73,6 +77,11 @@ static const tag_format_t tag_table[] =
{GCOV_TAG_OBJECT_SUMMARY, "OBJECT_SUMMARY", tag_summary},
{GCOV_TAG_PROGRAM_SUMMARY, "PROGRAM_SUMMARY", tag_summary},
{GCOV_TAG_MODULE_INFO, "MODULE INFO", tag_module_info},
+ {GCOV_TAG_PMU_LOAD_LATENCY_INFO, "PMU_LOAD_LATENCY_INFO",
+ tag_pmu_load_latency_info},
+ {GCOV_TAG_PMU_BRANCH_MISPREDICT_INFO, "PMU_BRANCH_MISPREDICT_INFO",
+ tag_pmu_branch_mispredict_info},
+ {GCOV_TAG_PMU_TOOL_HEADER, "PMU_TOOL_HEADER", tag_pmu_tool_header},
{0, NULL, NULL}
};
@@ -516,3 +525,45 @@ tag_module_info (const char *filename ATTRIBUTE_UNUSED,
printf (": %s [%s]", mod_info->source_filename, suffix);
}
}
+
+/* Read gcov tag GCOV_TAG_PMU_LOAD_LATENCY_INFO from the gcda file and
+ print the contents in a human readable form. */
+
+static void
+tag_pmu_load_latency_info (const char *filename ATTRIBUTE_UNUSED,
+ unsigned tag ATTRIBUTE_UNUSED, unsigned length)
+{
+ gcov_pmu_ll_info_t ll_info;
+ gcov_read_pmu_load_latency_info (&ll_info, length);
+ print_load_latency_line (stdout, &ll_info, 0);
+ if (ll_info.filename)
+ free (ll_info.filename);
+}
+
+/* Read gcov tag GCOV_TAG_PMU_BRANCH_MISPREDICT_INFO from the gcda
+ file and print the contents in a human readable form. */
+
+static void
+tag_pmu_branch_mispredict_info (const char *filename ATTRIBUTE_UNUSED,
+ unsigned tag ATTRIBUTE_UNUSED, unsigned length)
+{
+ gcov_pmu_brm_info_t brm_info;
+ gcov_read_pmu_branch_mispredict_info (&brm_info, length);
+ print_branch_mispredict_line (stdout, &brm_info, 0);
+ if (brm_info.filename)
+ free (brm_info.filename);
+}
+
+
+/* Read gcov tag GCOV_TAG_PMU_TOOL_HEADER from the gcda file and print
+ the contents in a human readable form. */
+
+static void
+tag_pmu_tool_header (const char *filename ATTRIBUTE_UNUSED,
+ unsigned tag ATTRIBUTE_UNUSED, unsigned length)
+{
+ gcov_pmu_tool_header_t tool_header;
+ gcov_read_pmu_tool_header (&tool_header, length);
+ print_pmu_tool_header (stdout, &tool_header, 0);
+ destroy_pmu_tool_header (&tool_header);
+}
diff --git a/gcc-4.4.3/gcc/gcov-io.c b/gcc-4.4.3/gcc/gcov-io.c
index 0e60b51de..f56f07cdf 100644
--- a/gcc-4.4.3/gcc/gcov-io.c
+++ b/gcc-4.4.3/gcc/gcov-io.c
@@ -25,7 +25,7 @@ along with GCC; see the file COPYING3. If not see
/* Redefine these here, rather than using the ones in system.h since
* including system.h leads to conflicting definitions of other
- * symbols and macros. */
+ * symbols and macros. */
#undef MIN
#define MIN(X,Y) ((X) < (Y) ? (X) : (Y))
@@ -38,6 +38,10 @@ static const gcov_unsigned_t *gcov_read_words (unsigned);
static void gcov_allocate (unsigned);
#endif
+#ifdef __GCOV_KERNEL__
+struct gcov_var gcov_var ATTRIBUTE_HIDDEN;
+#endif
+
static inline gcov_unsigned_t from_file (gcov_unsigned_t value)
{
#if !IN_LIBGCOV
@@ -59,6 +63,7 @@ static inline gcov_unsigned_t from_file (gcov_unsigned_t value)
opening an existing file and <0 on creating a new one.
MODE > 0 is read-only mode. */
+#ifndef __GCOV_KERNEL__
GCOV_LINKAGE int
#if IN_LIBGCOV
gcov_open (const char *name)
@@ -78,7 +83,7 @@ gcov_open (const char *name, int mode)
s_flock.l_len = 0; /* Until EOF. */
s_flock.l_pid = getpid ();
#endif
-
+
gcc_assert (!gcov_var.file);
gcov_var.start = 0;
gcov_var.offset = gcov_var.length = 0;
@@ -150,9 +155,26 @@ gcov_open (const char *name, int mode)
#endif
setbuf (gcov_var.file, (char *)0);
-
+
+ return 1;
+}
+#else /* __GCOV_KERNEL__ */
+
+extern _GCOV_FILE *gcov_current_file;
+
+GCOV_LINKAGE int
+gcov_open (const char *name)
+{
+ gcov_var.start = 0;
+ gcov_var.offset = gcov_var.length = 0;
+ gcov_var.overread = -1u;
+ gcov_var.error = 0;
+ gcov_var.file = gcov_current_file;
+ gcov_var.mode = 1;
+
return 1;
}
+#endif /* __GCOV_KERNEL__ */
/* Close the current gcov file. Flushes data to disk. Returns nonzero
on failure or error flag set. */
@@ -166,7 +188,7 @@ gcov_close (void)
if (gcov_var.offset && gcov_var.mode < 0)
gcov_write_block (gcov_var.offset);
#endif
- fclose (gcov_var.file);
+ _GCOV_fclose (gcov_var.file);
gcov_var.file = 0;
gcov_var.length = 0;
}
@@ -180,6 +202,76 @@ gcov_close (void)
}
#if !IN_LIBGCOV
+/* Read LEN words and construct load latency info LL_INFO. */
+
+GCOV_LINKAGE void
+gcov_read_pmu_load_latency_info (gcov_pmu_ll_info_t *ll_info,
+ gcov_unsigned_t len ATTRIBUTE_UNUSED)
+{
+ const char *filename;
+ ll_info->counts = gcov_read_unsigned ();
+ ll_info->self = gcov_read_unsigned ();
+ ll_info->cum = gcov_read_unsigned ();
+ ll_info->lt_10 = gcov_read_unsigned ();
+ ll_info->lt_32 = gcov_read_unsigned ();
+ ll_info->lt_64 = gcov_read_unsigned ();
+ ll_info->lt_256 = gcov_read_unsigned ();
+ ll_info->lt_1024 = gcov_read_unsigned ();
+ ll_info->gt_1024 = gcov_read_unsigned ();
+ ll_info->wself = gcov_read_unsigned ();
+ ll_info->code_addr = gcov_read_counter ();
+ ll_info->line = gcov_read_unsigned ();
+ ll_info->discriminator = gcov_read_unsigned ();
+ filename = gcov_read_string ();
+ if (filename)
+ ll_info->filename = xstrdup (filename);
+ else
+ ll_info->filename = 0;
+}
+
+/* Read LEN words and construct branch mispredict info BRM_INFO. */
+
+GCOV_LINKAGE void
+gcov_read_pmu_branch_mispredict_info (gcov_pmu_brm_info_t *brm_info,
+ gcov_unsigned_t len ATTRIBUTE_UNUSED)
+{
+ const char *filename;
+ brm_info->counts = gcov_read_unsigned ();
+ brm_info->self = gcov_read_unsigned ();
+ brm_info->cum = gcov_read_unsigned ();
+ brm_info->code_addr = gcov_read_counter ();
+ brm_info->line = gcov_read_unsigned ();
+ brm_info->discriminator = gcov_read_unsigned ();
+ filename = gcov_read_string ();
+ if (filename)
+ brm_info->filename = xstrdup (filename);
+ else
+ brm_info->filename = 0;
+}
+
+/* Read LEN words from an open gcov file and construct data into pmu
+ tool header TOOL_HEADER. */
+
+GCOV_LINKAGE void gcov_read_pmu_tool_header (gcov_pmu_tool_header_t *header,
+ gcov_unsigned_t len ATTRIBUTE_UNUSED)
+{
+ const char *str;
+ str = gcov_read_string ();
+ header->host_cpu = str ? xstrdup (str) : 0;
+ str = gcov_read_string ();
+ header->hostname = str ? xstrdup (str) : 0;
+ str = gcov_read_string ();
+ header->kernel_version = str ? xstrdup (str) : 0;
+ str = gcov_read_string ();
+ header->column_header = str ? xstrdup (str) : 0;
+ str = gcov_read_string ();
+ header->column_description = str ? xstrdup (str) : 0;
+ str = gcov_read_string ();
+ header->full_header = str ? xstrdup (str) : 0;
+}
+#endif
+
+#if !IN_LIBGCOV
/* Check if MAGIC is EXPECTED. Use it to determine endianness of the
file. Returns +1 for same endian, -1 for other endian and zero for
not EXPECTED. */
@@ -205,12 +297,12 @@ static void
gcov_allocate (unsigned length)
{
size_t new_size = gcov_var.alloc;
-
+
if (!new_size)
new_size = GCOV_BLOCK_SIZE;
new_size += length;
new_size *= 2;
-
+
gcov_var.alloc = new_size;
gcov_var.buffer = XRESIZEVAR (gcov_unsigned_t, gcov_var.buffer, new_size << 2);
}
@@ -222,7 +314,7 @@ gcov_allocate (unsigned length)
static void
gcov_write_block (unsigned size)
{
- if (fwrite (gcov_var.buffer, size << 2, 1, gcov_var.file) != 1)
+ if (_GCOV_fwrite (gcov_var.buffer, size << 2, 1, gcov_var.file) != 1)
gcov_var.error = 1;
gcov_var.start += size;
gcov_var.offset -= size;
@@ -240,7 +332,7 @@ GCOV_LINKAGE gcov_unsigned_t
gcov_string_length (const char *string)
{
gcov_unsigned_t len = (string) ? strlen (string) : 0;
- /* + 1 because of the length field. */
+ /* + 1 because of the length field. */
gcov_unsigned_t alloc = 1 + ((len + 4) >> 2);
/* Can not write a bigger than GCOV_BLOCK_SIZE string yet */
@@ -276,7 +368,7 @@ gcov_write_words (unsigned words)
#endif
result = &gcov_var.buffer[gcov_var.offset];
gcov_var.offset += words;
-
+
return result;
}
@@ -323,7 +415,7 @@ gcov_write_string (const char *string)
length = strlen (string);
alloc = (length + 4) >> 2;
}
-
+
buffer = gcov_write_words (1 + alloc);
buffer[0] = alloc;
@@ -331,7 +423,6 @@ gcov_write_string (const char *string)
memcpy (&buffer[1], string, length);
}
-
#if !IN_LIBGCOV
/* Write a tag TAG and reserve space for the record length. Return a
value to be used for gcov_write_length. */
@@ -344,7 +435,7 @@ gcov_write_tag (gcov_unsigned_t tag)
buffer[0] = tag;
buffer[1] = 0;
-
+
return result;
}
@@ -416,7 +507,7 @@ gcov_read_words (unsigned words)
{
const gcov_unsigned_t *result;
unsigned excess = gcov_var.length - gcov_var.offset;
-
+
gcc_assert (gcov_var.mode > 0);
gcc_assert (words < GCOV_BLOCK_SIZE);
if (excess < words)
@@ -440,7 +531,7 @@ gcov_read_words (unsigned words)
gcov_allocate (gcov_var.length + words);
excess = gcov_var.alloc - gcov_var.length;
#endif
- excess = fread (gcov_var.buffer + gcov_var.length,
+ excess = _GCOV_fread (gcov_var.buffer + gcov_var.length,
1, excess << 2, gcov_var.file) >> 2;
gcov_var.length += excess;
if (gcov_var.length < words)
@@ -498,7 +589,7 @@ GCOV_LINKAGE const char *
gcov_read_string (void)
{
unsigned length = gcov_read_unsigned ();
-
+
if (!length)
return 0;
@@ -511,7 +602,7 @@ gcov_read_summary (struct gcov_summary *summary)
{
unsigned ix;
struct gcov_ctr_summary *csum;
-
+
summary->checksum = gcov_read_unsigned ();
for (csum = summary->ctrs, ix = GCOV_COUNTERS_SUMMABLE; ix--; csum++)
{
@@ -523,6 +614,31 @@ gcov_read_summary (struct gcov_summary *summary)
}
}
+#ifndef __GCOV_KERNEL__
+#if IN_GCOV != 1
+/* Delete pmu tool header TOOL_HEADER. */
+
+GCOV_LINKAGE void
+destroy_pmu_tool_header (gcov_pmu_tool_header_t *tool_header)
+{
+ if (!tool_header)
+ return;
+ if (tool_header->host_cpu)
+ free (tool_header->host_cpu);
+ if (tool_header->hostname)
+ free (tool_header->hostname);
+ if (tool_header->kernel_version)
+ free (tool_header->kernel_version);
+ if (tool_header->column_header)
+ free (tool_header->column_header);
+ if (tool_header->column_description)
+ free (tool_header->column_description);
+ if (tool_header->full_header)
+ free (tool_header->full_header);
+}
+#endif
+#endif /* __GCOV_KERNEL__ */
+
#if !IN_LIBGCOV && IN_GCOV != 1
/* Read LEN words (unsigned type) and construct MOD_INFO. */
@@ -580,6 +696,10 @@ gcov_read_module_info (struct gcov_module_info *mod_info,
GCOV_LINKAGE void
gcov_sync (gcov_position_t base, gcov_unsigned_t length)
{
+#ifdef __GCOV_KERNEL__
+ /* should not reach this point */
+ gcc_assert (0);
+#else /* __GCOV_KERNEL__ */
gcc_assert (gcov_var.mode > 0);
base += length;
if (base - gcov_var.start <= gcov_var.length)
@@ -587,9 +707,93 @@ gcov_sync (gcov_position_t base, gcov_unsigned_t length)
else
{
gcov_var.offset = gcov_var.length = 0;
- fseek (gcov_var.file, base << 2, SEEK_SET);
- gcov_var.start = ftell (gcov_var.file) >> 2;
+ _GCOV_fseek (gcov_var.file, base << 2, SEEK_SET);
+ gcov_var.start = _GCOV_ftell (gcov_var.file) >> 2;
}
+#endif /* __GCOV_KERNEL__ */
+}
+#endif
+
+#ifndef __GCOV_KERNEL__
+/* Convert an unsigned NUMBER to a percentage after dividing by
+ 100. */
+
+GCOV_LINKAGE float
+convert_unsigned_to_pct (const unsigned number)
+{
+ return (float)number / 100.0;
+}
+#endif /* __GCOV_KERNEL__ */
+
+#if !IN_LIBGCOV && IN_GCOV != 1
+/* Print load latency information given by LL_INFO in a human readable
+ format into an open output file pointed by FP. If NEWLINE is
+ nonzero, then a trailing newline is also printed. */
+
+GCOV_LINKAGE void
+print_load_latency_line (FILE *fp, const gcov_pmu_ll_info_t *ll_info,
+ const int print_newline)
+{
+ if (!ll_info)
+ return;
+ fprintf (fp, " %u %.2f%% %.2f%% %.2f%% %.2f%% %.2f%% %.2f%% %.2f%% "
+ "%.2f%% %.2f%% " HOST_WIDEST_INT_PRINT_HEX " %s %d %d",
+ ll_info->counts,
+ convert_unsigned_to_pct (ll_info->self),
+ convert_unsigned_to_pct (ll_info->cum),
+ convert_unsigned_to_pct (ll_info->lt_10),
+ convert_unsigned_to_pct (ll_info->lt_32),
+ convert_unsigned_to_pct (ll_info->lt_64),
+ convert_unsigned_to_pct (ll_info->lt_256),
+ convert_unsigned_to_pct (ll_info->lt_1024),
+ convert_unsigned_to_pct (ll_info->gt_1024),
+ convert_unsigned_to_pct (ll_info->wself),
+ ll_info->code_addr,
+ ll_info->filename,
+ ll_info->line,
+ ll_info->discriminator);
+ if (print_newline)
+ fprintf (fp, "\n");
+}
+
+/* Print BRM_INFO into the file pointed by FP. If PRINT_NEWLINE is
+ * non-zero then output a trailing newline as well. */
+
+GCOV_LINKAGE void
+print_branch_mispredict_line (FILE *fp, const gcov_pmu_brm_info_t *brm_info,
+ const int print_newline)
+{
+ if (!brm_info)
+ return;
+ fprintf (fp, " %u %.2f%% %.2f%% %llx %s %d %d",
+ brm_info->counts,
+ convert_unsigned_to_pct (brm_info->self),
+ convert_unsigned_to_pct (brm_info->cum),
+ (long long unsigned int)brm_info->code_addr,
+ brm_info->filename,
+ brm_info->line,
+ brm_info->discriminator);
+ if (print_newline)
+ fprintf (fp, "\n");
+}
+
+/* Print TOOL_HEADER into the file pointed by FP. If PRINT_NEWLINE is
+ non-zero then output a trailing newline as well. */
+
+GCOV_LINKAGE void
+print_pmu_tool_header (FILE *fp, gcov_pmu_tool_header_t *tool_header,
+ const int print_newline)
+{
+ if (!tool_header)
+ return;
+ fprintf (fp, "\nhost_cpu: %s\n", tool_header->host_cpu);
+ fprintf (fp, "hostname: %s\n", tool_header->hostname);
+ fprintf (fp, "kernel_version: %s\n", tool_header->kernel_version);
+ fprintf (fp, "column_header: %s\n", tool_header->column_header);
+ fprintf (fp, "column_description: %s\n", tool_header->column_description);
+ fprintf (fp, "full_header: %s\n", tool_header->full_header);
+ if (print_newline)
+ fprintf (fp, "\n");
}
#endif
@@ -602,8 +806,8 @@ gcov_seek (gcov_position_t base)
gcc_assert (gcov_var.mode < 0);
if (gcov_var.offset)
gcov_write_block (gcov_var.offset);
- fseek (gcov_var.file, base << 2, SEEK_SET);
- gcov_var.start = ftell (gcov_var.file) >> 2;
+ _GCOV_fseek (gcov_var.file, base << 2, SEEK_SET);
+ gcov_var.start = _GCOV_ftell (gcov_var.file) >> 2;
}
/* Truncate the gcov file at the current position. */
@@ -611,15 +815,20 @@ gcov_seek (gcov_position_t base)
GCOV_LINKAGE void
gcov_truncate (void)
{
+#ifdef __GCOV_KERNEL__
+ /* should not reach this point */
+ gcc_assert (0);
+#else /* __GCOV_KERNEL__ */
long offs;
int filenum;
gcc_assert (gcov_var.mode < 0);
if (gcov_var.offset)
gcov_write_block (gcov_var.offset);
- offs = ftell (gcov_var.file);
- filenum = fileno (gcov_var.file);
- if (offs == -1 || filenum == -1 || ftruncate (filenum, offs))
+ offs = _GCOV_ftell (gcov_var.file);
+ filenum = _GCOV_fileno (gcov_var.file);
+ if (offs == -1 || filenum == -1 || _GCOV_ftruncate (filenum, offs))
gcov_var.error = 1;
+#endif /* __GCOV_KERNEL__ */
}
#endif
@@ -630,10 +839,138 @@ GCOV_LINKAGE time_t
gcov_time (void)
{
struct stat status;
-
+
if (fstat (fileno (gcov_var.file), &status))
return 0;
else
return status.st_mtime;
}
#endif /* IN_GCOV */
+
+#ifndef __GCOV_KERNEL__
+union gcov_float_converter
+{
+ gcov_float_t f;
+ gcov_type t;
+};
+
+/* Convert from gcov_float_t (double) to gcov_type. */
+gcov_type
+gcov_float_to_type (gcov_float_t f)
+{
+ union gcov_float_converter u;
+ u.f = f;
+ return u.t;
+}
+
+/* Convert from gcov_type and gcov_float_t (double). */
+gcov_float_t
+gcov_type_to_float (gcov_type t)
+{
+ union gcov_float_converter u;
+ u.t = t;
+ return u.f;
+}
+#endif /* __GCOV_KERNEL__ */
+
+#ifdef __GCOV_KERNEL__
+
+/* File fclose operation in kernel mode. */
+
+int
+kernel_file_fclose (gcov_kernel_vfile *fp)
+{
+ return 0;
+}
+
+/* File ftell operation in kernel mode. It currently should not
+ be called. */
+
+long
+kernel_file_ftell (gcov_kernel_vfile *fp)
+{
+ gcc_assert (0); /* should not reach here */
+ return 0;
+}
+
+/* File fseek operation in kernel mode. It should only be called
+ with OFFSET==0 and WHENCE==0 to a freshly opened file. */
+
+int
+kernel_file_fseek (gcov_kernel_vfile *fp, long offset, int whence)
+{
+ gcc_assert (offset == 0 && whence == 0 && fp->count == 0);
+ return 0;
+}
+
+/* File ftruncate operation in kernel mode. It currently should not
+ be called. */
+
+int
+kernel_file_ftruncate (gcov_kernel_vfile *fp, off_t value)
+{
+ gcc_assert (0); /* should not reach here */
+ return 0;
+}
+
+/* File fread operation in kernel mode. It currently should not
+ be called. */
+
+int
+kernel_file_fread (void *ptr, size_t size, size_t nitems,
+ gcov_kernel_vfile *fp)
+{
+ gcc_assert (0); /* should not reach here */
+ return 0;
+}
+
+/* File fwrite operation in kernel mode. It outputs the data
+ to a buffer in the virual file. */
+
+int
+kernel_file_fwrite (const void *ptr, size_t size,
+ size_t nitems, gcov_kernel_vfile *fp)
+{
+ char *vbuf;
+ unsigned vsize, vpos;
+ unsigned len;
+
+ if (!fp) return 0;
+
+ vbuf = fp->buf;
+ vsize = fp->size;
+ vpos = fp->count;
+
+ if (vsize <= vpos)
+ {
+ printk (KERN_ERR
+ "GCOV_KERNEL: something wrong: vbuf=%p vsize=%u vpos=%u\n",
+ vbuf, vsize, vpos);
+ return 0;
+ }
+ len = vsize - vpos;
+ len /= size;
+
+ if (len > nitems)
+ len = nitems;
+
+ memcpy (vbuf+vpos, ptr, size*len);
+ fp->count += len*size;
+
+ if (len != nitems)
+ printk (KERN_ERR
+ "GCOV_KERNEL: something wrong: size=%lu nitems=%lu ret=%d\n",
+ size, nitems, len);
+ return len;
+}
+
+/* File fileno operation in kernel mode. It currently should not
+ be called. */
+
+int
+kernel_file_fileno (gcov_kernel_vfile *fp)
+{
+ gcc_assert (0); /* should not reach here */
+ return 0;
+}
+#endif /* GCOV_KERNEL */
diff --git a/gcc-4.4.3/gcc/gcov-io.h b/gcc-4.4.3/gcc/gcov-io.h
index ffee38e53..7584f4c4f 100644
--- a/gcc-4.4.3/gcc/gcov-io.h
+++ b/gcc-4.4.3/gcc/gcov-io.h
@@ -61,7 +61,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
file. It need not be an absolute time stamp, merely a ticker that
increments fast enough and cycles slow enough to distinguish
different compile/run/compile cycles.
-
+
Although the ident and version are formally 32 bit numbers, they
are derived from 4 character ASCII strings. The version number
consists of the single character major version number, a two
@@ -164,6 +164,89 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#ifndef GCC_GCOV_IO_H
#define GCC_GCOV_IO_H
+typedef double gcov_float_t;
+#ifdef __KERNEL__
+#ifndef __GCOV_KERNEL__
+#define __GCOV_KERNEL__
+#endif /* __GCOV_KERNEL__ */
+#endif /* __KERNEL__ */
+
+#ifdef __GCOV_KERNEL__
+#define GCOV_LINKAGE /* nothing */
+
+/* We need the definitions for
+ BITS_PER_UNIT and
+ LONG_LONG_TYPE_SIZE
+ They are defined in gcc/defaults.h and gcc/config/<arch_depend_files>
+ (like, gcc/config/i386/i386.h). It's not easy to included them
+ cleanly. So I hardcoded the value for x86. */
+#define BITS_PER_UNIT 8
+#define LONG_LONG_TYPE_SIZE 64
+
+/* There are many gcc_assertions. Set the vaule to 1 if we want a warning
+ message if the assertion fails. */
+#ifndef ENABLE_ASSERT_CHECKING
+#define ENABLE_ASSERT_CHECKING 1
+#endif
+
+#include <linux/fs.h>
+#endif /* __GCOV_KERNEL__ */
+
+/* Wrappers to the file operations. */
+#ifndef __GCOV_KERNEL__
+# define _GCOV_FILE FILE
+# define _GCOV_fclose fclose
+# define _GCOV_ftell ftell
+# define _GCOV_fseek fseek
+# define _GCOV_ftruncate ftruncate
+# define _GCOV_fread fread
+# define _GCOV_fwrite fwrite
+# define _GCOV_fread fread
+# define _GCOV_fileno fileno
+#else /* __GCOV_KERNEL__ */
+/* In Linux kernel mode, a virtual file is used for file operations. */
+struct gcov_info;
+typedef struct {
+ long size; /* size of buf */
+ long count; /* element written into buf */
+ struct gcov_info *info;
+ char buf[0];
+} gcov_kernel_vfile;
+
+# define _GCOV_FILE gcov_kernel_vfile
+
+/* gcc_assert() prints out a warning if the check fails. It
+ will not abort. */
+#if ENABLE_ASSERT_CHECKING
+# define gcc_assert(EXPR) \
+ ((void)(!(EXPR) ? printk (KERN_WARNING \
+ "GCOV assertion fails: func=%s line=%d\n", \
+ __FUNCTION__, __LINE__), 0 : 0))
+#else
+# define gcc_assert(EXPR) ((void)(0 && (EXPR)))
+#endif
+
+/* Wrappers to the file operations. */
+# define _GCOV_fclose kernel_file_fclose
+# define _GCOV_ftell kernel_file_ftell
+# define _GCOV_fseek kernel_file_fseek
+# define _GCOV_ftruncate kernel_file_ftruncate
+# define _GCOV_fread kernel_file_fread
+# define _GCOV_fwrite kernel_file_fwrite
+# define _GCOV_fileno kernel_file_fileno
+
+/* Declarations for virtual files operations. */
+extern int kernel_file_fclose (gcov_kernel_vfile *);
+extern long kernel_file_ftell (gcov_kernel_vfile *);
+extern int kernel_file_fseek (gcov_kernel_vfile *, long, int);
+extern int kernel_file_ftruncate (gcov_kernel_vfile *, off_t);
+extern int kernel_file_fread (void *, size_t, size_t,
+ gcov_kernel_vfile *);
+extern int kernel_file_fwrite (const void *, size_t, size_t,
+ gcov_kernel_vfile *);
+extern int kernel_file_fileno(gcov_kernel_vfile *);
+#endif /* GCOV_KERNEL */
+
#if IN_LIBGCOV
#undef FUNC_ID_WIDTH
@@ -207,7 +290,7 @@ typedef signed gcov_type __attribute__ ((mode (QI)));
#define FUNC_ID_WIDTH 16
#define FUNC_ID_MASK ((1 << FUNC_ID_WIDTH) - 1)
#endif
-#endif /* BITS_PER_UNIT == 16 */
+#endif /* BITS_PER_UNIT == 16 */
#endif /* BITS_PER_UNIT == 8 */
@@ -265,7 +348,9 @@ typedef HOST_WIDEST_INT gcov_type;
is not also used in a DSO. */
#if IN_LIBGCOV
+#ifndef __GCOV_KERNEL__
#include "tconfig.h"
+#endif /* __GCOV_KERNEL__ */
#define gcov_var __gcov_var
#define gcov_open __gcov_open
@@ -288,6 +373,11 @@ typedef HOST_WIDEST_INT gcov_type;
#define gcov_read_summary __gcov_read_summary
#define gcov_read_module_info __gcov_read_module_info
#define gcov_sort_n_vals __gcov_sort_n_vals
+#define gcov_read_pmu_load_latency_info __gcov_read_pmu_load_latency_info
+#define gcov_read_pmu_branch_mispredict_info __gcov_read_pmu_branch_mispredict_info
+#define gcov_read_pmu_tool_header __gcov_read_pmu_tool_header
+#define destroy_pmu_tool_header __destroy_pmu_tool_header
+
/* Poison these, so they don't accidentally slip in. */
#pragma GCC poison gcov_write_tag gcov_write_length
@@ -352,6 +442,13 @@ typedef HOST_WIDEST_INT gcov_type;
#define GCOV_TAG_SUMMARY_LENGTH \
(1 + GCOV_COUNTERS_SUMMABLE * (2 + 3 * 2))
#define GCOV_TAG_MODULE_INFO ((gcov_unsigned_t)0xa4000000)
+#define GCOV_TAG_PMU_LOAD_LATENCY_INFO ((gcov_unsigned_t)0xa5000000)
+#define GCOV_TAG_PMU_LOAD_LATENCY_LENGTH(filename) \
+ (gcov_string_length (filename) + 12 + 2)
+#define GCOV_TAG_PMU_BRANCH_MISPREDICT_INFO ((gcov_unsigned_t)0xa7000000)
+#define GCOV_TAG_PMU_BRANCH_MISPREDICT_LENGTH(filename) \
+ (gcov_string_length (filename) + 5 + 2)
+#define GCOV_TAG_PMU_TOOL_HEADER ((gcov_unsigned_t)0xa9000000)
/* Counters that are collected. */
#define GCOV_COUNTER_ARCS 0 /* Arc transitions. */
@@ -366,29 +463,32 @@ typedef HOST_WIDEST_INT gcov_type;
#define GCOV_COUNTER_V_POW2 2 /* Histogram of exact power2 logarithm
of a value. */
#define GCOV_COUNTER_V_SINGLE 3 /* The most common value of expression. */
-#define GCOV_COUNTER_V_DELTA 4 /* The most common difference between
+#define GCOV_COUNTER_V_SINGLE_FLOAT 4 /* The most common float value */
+#define GCOV_COUNTER_V_DELTA 5 /* The most common difference between
consecutive values of expression. */
-#define GCOV_COUNTER_V_INDIR 5 /* The most common indirect address */
-#define GCOV_COUNTER_AVERAGE 6 /* Compute average value passed to the
+#define GCOV_COUNTER_V_INDIR 6 /* The most common indirect address */
+#define GCOV_COUNTER_AVERAGE 7 /* Compute average value passed to the
counter. */
-#define GCOV_COUNTER_IOR 7 /* IOR of the all values passed to
+#define GCOV_COUNTER_IOR 8 /* IOR of the all values passed to
counter. */
-#define GCOV_COUNTER_ICALL_TOPNV 8 /* Top N value tracking for indirect calls */
-#define GCOV_LAST_VALUE_COUNTER 8 /* The last of counters used for value
+#define GCOV_COUNTER_ICALL_TOPNV 9 /* Top N value tracking for indirect calls */
+#define GCOV_LAST_VALUE_COUNTER 9 /* The last of counters used for value
profiling. */
-#define GCOV_COUNTER_DIRECT_CALL 9 /* Direct call counts. */
-#define GCOV_COUNTERS 10
+#define GCOV_COUNTER_DIRECT_CALL 10 /* Direct call counts. */
+#define GCOV_COUNTER_REUSE_DIST 11 /* Reuse distance measure. */
+#define GCOV_COUNTERS 12
/* Number of counters used for value profiling. */
#define GCOV_N_VALUE_COUNTERS \
(GCOV_LAST_VALUE_COUNTER - GCOV_FIRST_VALUE_COUNTER + 1)
-
+
/* A list of human readable names of the counters */
#define GCOV_COUNTER_NAMES {"arcs", "interval", "pow2", "single", \
- "delta","indirect_call", "average", "ior", \
- "indirect_call_topn", "direct_call"}
-
+ "single_float", "delta","indirect_call", \
+ "average", "ior", "indirect_call_topn", \
+ "direct_call", "reuse_distance"}
+
#define GCOV_ICALL_TOPN_VAL 2 /* Track two hottest callees */
#define GCOV_ICALL_TOPN_NCOUNTS 9 /* The number of counter entries per icall callsite */
/* Names of merge functions for counters. */
@@ -396,13 +496,15 @@ typedef HOST_WIDEST_INT gcov_type;
"__gcov_merge_add", \
"__gcov_merge_add", \
"__gcov_merge_single", \
+ "__gcov_merge_single_float", \
"__gcov_merge_delta", \
"__gcov_merge_single", \
"__gcov_merge_add", \
"__gcov_merge_ior", \
"__gcov_merge_icall_topn",\
- "__gcov_merge_dc" }
-
+ "__gcov_merge_dc", \
+ "__gcov_merge_reusedist"}
+
/* Convert a counter index to a tag. */
#define GCOV_TAG_FOR_COUNTER(COUNT) \
(GCOV_TAG_COUNTER_BASE + ((gcov_unsigned_t)(COUNT) << 17))
@@ -493,6 +595,91 @@ extern unsigned primary_module_id;
&& !((module_infos[0]->lang & GCOV_MODULE_ASM_STMTS) \
&& flag_ripa_disallow_asm_modules))
+/* Information about the hardware performance monitoring unit. */
+struct gcov_pmu_info
+{
+ const char *pmu_profile_filename; /* pmu profile filename */
+ const char *pmu_tool; /* canonical pmu tool options */
+ gcov_unsigned_t pmu_top_n_address; /* how many top addresses to symbolize */
+};
+
+/* Information about the PMU tool header. */
+typedef struct gcov_pmu_tool_header {
+ char *host_cpu;
+ char *hostname;
+ char *kernel_version;
+ char *column_header;
+ char *column_description;
+ char *full_header;
+} gcov_pmu_tool_header_t;
+
+/* Available only for PMUs which support PEBS or IBS using pfmon
+ tool. If any field here is changed, the length computation in
+ GCOV_TAG_PMU_LOAD_LATENCY_LENGTH must be updated as well. All
+ percentages are multiplied by 100 to make them out of 10000 and
+ only integer part is kept. */
+typedef struct gcov_pmu_load_latency_info
+{
+ gcov_unsigned_t counts; /* raw count of samples */
+ gcov_unsigned_t self; /* per 10k of total samples */
+ gcov_unsigned_t cum; /* per 10k cumulative weight */
+ gcov_unsigned_t lt_10; /* per 10k with latency <= 10 cycles */
+ gcov_unsigned_t lt_32; /* per 10k with latency <= 32 cycles */
+ gcov_unsigned_t lt_64; /* per 10k with latency <= 64 cycles */
+ gcov_unsigned_t lt_256; /* per 10k with latency <= 256 cycles */
+ gcov_unsigned_t lt_1024; /* per 10k with latency <= 1024 cycles */
+ gcov_unsigned_t gt_1024; /* per 10k with latency > 1024 cycles */
+ gcov_unsigned_t wself; /* weighted average cost of this miss in cycles */
+ gcov_type code_addr; /* the actual miss address (pc+1 for Intel) */
+ gcov_unsigned_t line; /* line number corresponding to this miss */
+ gcov_unsigned_t discriminator; /* discriminator information for this miss */
+ char *filename; /* filename corresponding to this miss */
+} gcov_pmu_ll_info_t;
+
+/* This structure is used during runtime as well as in gcov. */
+typedef struct load_latency_infos
+{
+ /* An array describing the total number of load latency fields. */
+ gcov_pmu_ll_info_t **ll_array;
+ /* The total number of entries in the load latency array. */
+ unsigned ll_count;
+ /* The total number of entries currently allocated in the array.
+ Used for bookkeeping. */
+ unsigned alloc_ll_count;
+ /* PMU tool header */
+ gcov_pmu_tool_header_t *pmu_tool_header;
+} ll_infos_t;
+
+/* Available only for PMUs which support PEBS or IBS using pfmon
+ tool. If any field here is changed, the length computation in
+ GCOV_TAG_PMU_BR_MISPREDICT_LENGTH must be updated as well. All
+ percentages are multiplied by 100 to make them out of 10000 and
+ only integer part is kept. */
+typedef struct gcov_pmu_branch_mispredict_info
+{
+ gcov_unsigned_t counts; /* raw count of samples */
+ gcov_unsigned_t self; /* per 10k of total samples */
+ gcov_unsigned_t cum; /* per 10k cumulative weight */
+ gcov_type code_addr; /* the actual mispredict address */
+ gcov_unsigned_t line; /* line number corresponding to this event */
+ gcov_unsigned_t discriminator; /* discriminator for this event */
+ char *filename; /* filename corresponding to this event */
+} gcov_pmu_brm_info_t;
+
+/* This structure is used during runtime as well as in gcov. */
+typedef struct branch_mispredict_infos
+{
+ /* An array describing the total number of mispredict entries. */
+ gcov_pmu_brm_info_t **brm_array;
+ /* The total number of entries in the above array. */
+ unsigned brm_count;
+ /* The total number of entries currently allocated in the array.
+ Used for bookkeeping. */
+ unsigned alloc_brm_count;
+ /* PMU tool header */
+ gcov_pmu_tool_header_t *pmu_tool_header;
+} brm_infos_t;
+
/* Structures embedded in coveraged program. The structures generated
by write_profile must match these. */
@@ -500,7 +687,7 @@ extern unsigned primary_module_id;
/* Information about a single function. This uses the trailing array
idiom. The number of counters is determined from the counter_mask
in gcov_info. We hold an array of function info, so have to
- explicitly calculate the correct array stride.
+ explicitly calculate the correct array stride.
"ident" is no longer used in hash computation. Additionally,
"name" is used in hash computation. This makes the profile data
@@ -549,6 +736,13 @@ struct gcov_info
is. */
};
+/* Information about a single imported module. */
+struct dyn_imp_mod
+{
+ const struct gcov_info *imp_mod;
+ double weight;
+};
+
/* Register a new object file module. */
extern void __gcov_init (struct gcov_info *) ATTRIBUTE_HIDDEN;
@@ -561,6 +755,9 @@ extern void __gcov_merge_add (gcov_type *, unsigned) ATTRIBUTE_HIDDEN;
/* The merge function to choose the most common value. */
extern void __gcov_merge_single (gcov_type *, unsigned) ATTRIBUTE_HIDDEN;
+/* The merge function to choose the most common value. */
+extern void __gcov_merge_single_float (gcov_type *, unsigned) ATTRIBUTE_HIDDEN;
+
/* The merge function to choose the most common difference between
consecutive values. */
extern void __gcov_merge_delta (gcov_type *, unsigned) ATTRIBUTE_HIDDEN;
@@ -571,13 +768,17 @@ extern void __gcov_merge_ior (gcov_type *, unsigned) ATTRIBUTE_HIDDEN;
/* The merge function used for direct call counters. */
extern void __gcov_merge_dc (gcov_type *, unsigned) ATTRIBUTE_HIDDEN;
+/* The merge function used for reuse distance counters. */
+extern void __gcov_merge_reusedist (gcov_type *, unsigned) ATTRIBUTE_HIDDEN;
+
/* The merge function used for indirect call counters. */
extern void __gcov_merge_icall_topn (gcov_type *, unsigned) ATTRIBUTE_HIDDEN;
/* The profiler functions. */
-extern void __gcov_interval_profiler (gcov_type *, gcov_type, int, unsigned);
+extern void __gcov_interval_profiler (gcov_type *, gcov_type, int, unsigned);
extern void __gcov_pow2_profiler (gcov_type *, gcov_type);
extern void __gcov_one_value_profiler (gcov_type *, gcov_type);
+extern void __gcov_one_float_value_profiler (gcov_type *, gcov_float_t);
extern void __gcov_indirect_call_profiler (gcov_type *, gcov_type, void *, void *);
extern void __gcov_indirect_call_topn_profiler (void *, void *, gcov_unsigned_t) ATTRIBUTE_HIDDEN;
extern void __gcov_direct_call_profiler (void *, void *, gcov_unsigned_t) ATTRIBUTE_HIDDEN;
@@ -585,6 +786,12 @@ extern void __gcov_average_profiler (gcov_type *, gcov_type);
extern void __gcov_ior_profiler (gcov_type *, gcov_type);
extern void __gcov_sort_n_vals (gcov_type *value_array, int n);
+/* Initialize/start/stop/dump performance monitoring unit (PMU) profile */
+void __gcov_init_pmu_profiler (struct gcov_pmu_info *) ATTRIBUTE_HIDDEN;
+void __gcov_start_pmu_profiler (void) ATTRIBUTE_HIDDEN;
+void __gcov_stop_pmu_profiler (void) ATTRIBUTE_HIDDEN;
+void __gcov_end_pmu_profiler (void) ATTRIBUTE_HIDDEN;
+
#ifndef inhibit_libc
/* The wrappers around some library functions.. */
extern pid_t __gcov_fork (void) ATTRIBUTE_HIDDEN;
@@ -604,9 +811,9 @@ extern int __gcov_execve (const char *, char *const [], char *const [])
/* Optimum number of gcov_unsigned_t's read from or written to disk. */
#define GCOV_BLOCK_SIZE (1 << 10)
-GCOV_LINKAGE struct gcov_var
+struct gcov_var
{
- FILE *file;
+ _GCOV_FILE *file;
gcov_position_t start; /* Position of first byte of block */
unsigned offset; /* Read/write position within the block. */
unsigned length; /* Read limit in the block. */
@@ -626,7 +833,15 @@ GCOV_LINKAGE struct gcov_var
size_t alloc;
gcov_unsigned_t *buffer;
#endif
-} gcov_var ATTRIBUTE_HIDDEN;
+};
+
+/* In kernel mode, move gcov_var definition to gcov-io.c
+ to avoid dulipcate definitions. */
+#ifndef __GCOV_KERNEL__
+GCOV_LINKAGE struct gcov_var gcov_var ATTRIBUTE_HIDDEN;
+#else
+extern struct gcov_var gcov_var;
+#endif
/* Functions for reading and writing gcov files. In libgcov you can
open the file for reading then writing. Elsewhere you can open the
@@ -652,11 +867,33 @@ static int gcov_is_error (void);
GCOV_LINKAGE gcov_unsigned_t gcov_read_unsigned (void) ATTRIBUTE_HIDDEN;
GCOV_LINKAGE gcov_type gcov_read_counter (void) ATTRIBUTE_HIDDEN;
GCOV_LINKAGE void gcov_read_summary (struct gcov_summary *) ATTRIBUTE_HIDDEN;
+GCOV_LINKAGE void gcov_read_pmu_load_latency_info (
+ gcov_pmu_ll_info_t *ll_info, gcov_unsigned_t len) ATTRIBUTE_HIDDEN;
+GCOV_LINKAGE void gcov_read_pmu_branch_mispredict_info (
+ gcov_pmu_brm_info_t *brm_info, gcov_unsigned_t len) ATTRIBUTE_HIDDEN;
+GCOV_LINKAGE void gcov_read_pmu_tool_header (
+ gcov_pmu_tool_header_t *tool_header, gcov_unsigned_t len) ATTRIBUTE_HIDDEN;
+
#if !IN_LIBGCOV && IN_GCOV != 1
GCOV_LINKAGE void gcov_read_module_info (struct gcov_module_info *mod_info,
gcov_unsigned_t len) ATTRIBUTE_HIDDEN;
+GCOV_LINKAGE void print_load_latency_line (FILE *fp,
+ const gcov_pmu_ll_info_t *ll_info,
+ const int print_newline);
+GCOV_LINKAGE void print_branch_mispredict_line (
+ FILE *fp, const gcov_pmu_brm_info_t *brm_info, const int print_newline);
+GCOV_LINKAGE void print_pmu_tool_header (FILE *fp,
+ gcov_pmu_tool_header_t *tool_header,
+ const int print_newline);
#endif
+
+#if IN_GCOV != 1
+GCOV_LINKAGE void destroy_pmu_tool_header (gcov_pmu_tool_header_t *tool_header)
+ ATTRIBUTE_HIDDEN;
+#endif
+
GCOV_LINKAGE const char *gcov_read_string (void) ATTRIBUTE_HIDDEN;
+GCOV_LINKAGE float convert_unsigned_to_pct (const unsigned number);
#if IN_LIBGCOV
/* Available only in libgcov */
@@ -669,13 +906,14 @@ GCOV_LINKAGE void gcov_write_summary (gcov_unsigned_t /*tag*/,
GCOV_LINKAGE void gcov_write_module_infos (struct gcov_info *mod_info)
ATTRIBUTE_HIDDEN;
-GCOV_LINKAGE const struct gcov_info **
+GCOV_LINKAGE const struct dyn_imp_mod **
gcov_get_sorted_import_module_array (struct gcov_info *mod_info, unsigned *len)
ATTRIBUTE_HIDDEN;
static void gcov_rewrite (void);
GCOV_LINKAGE void gcov_seek (gcov_position_t /*position*/) ATTRIBUTE_HIDDEN;
GCOV_LINKAGE void gcov_truncate (void) ATTRIBUTE_HIDDEN;
GCOV_LINKAGE gcov_unsigned_t gcov_string_length (const char *) ATTRIBUTE_HIDDEN;
+GCOV_LINKAGE unsigned gcov_gcda_file_size (struct gcov_info *);
#else
/* Available outside libgcov */
GCOV_LINKAGE void gcov_sync (gcov_position_t /*base*/,
@@ -725,10 +963,14 @@ gcov_rewrite (void)
gcov_var.mode = -1;
gcov_var.start = 0;
gcov_var.offset = 0;
- fseek (gcov_var.file, 0L, SEEK_SET);
+ _GCOV_fseek (gcov_var.file, 0L, SEEK_SET);
}
#endif
#endif /* IN_LIBGCOV >= 0 */
+/* Convert between gcov_type and gcov_float_t. */
+gcov_type gcov_float_to_type(gcov_float_t f);
+gcov_float_t gcov_type_to_float(gcov_type t);
+
#endif /* GCC_GCOV_IO_H */
diff --git a/gcc-4.4.3/gcc/gcov.c b/gcc-4.4.3/gcc/gcov.c
index d67e621bc..38937917e 100644
--- a/gcc-4.4.3/gcc/gcov.c
+++ b/gcc-4.4.3/gcc/gcov.c
@@ -209,6 +209,15 @@ typedef struct coverage_info
char *name;
} coverage_t;
+/* Describes PMU profile data for either one source file or for the
+ entire program. */
+
+typedef struct pmu_data
+{
+ ll_infos_t ll_infos;
+ brm_infos_t brm_infos;
+} pmu_data_t;
+
/* Describes a single line of source. Contains a chain of basic blocks
with code on it. */
@@ -242,6 +251,8 @@ typedef struct source_info
coverage_t coverage;
+ pmu_data_t *pmu_data; /* PMU profile information for this file. */
+
/* Functions in this source file. These are in ascending line
number order. */
function_t *functions;
@@ -301,6 +312,10 @@ static int flag_branches = 0;
/* Show unconditional branches too. */
static int flag_unconditional = 0;
+/* Output performance monitoring unit (PMU) data, if available. */
+
+static int flag_pmu_profile = 0;
+
/* Output a gcov file if this is true. This is on by default, and can
be turned off by the -n option. */
@@ -340,6 +355,18 @@ static int flag_preserve_paths = 0;
static int flag_counts = 0;
+/* PMU profile default filename. */
+
+static char pmu_profile_default_filename[] = "pmuprofile.gcda";
+
+/* PMU profile filename where the PMU profile data is read from. */
+
+static char *pmu_profile_filename = 0;
+
+/* PMU data for the entire program. */
+
+static pmu_data_t pmu_global_info;
+
/* Forward declarations. */
static void fnotice (FILE *, const char *, ...) ATTRIBUTE_PRINTF_2;
static int process_args (int, char **);
@@ -361,6 +388,17 @@ static int output_branch_count (FILE *, int, const arc_t *);
static void output_lines (FILE *, const source_t *);
static char *make_gcov_file_name (const char *, const char *);
static void release_structures (void);
+static void process_pmu_profile (void);
+static void filter_pmu_data_lines (source_t *src);
+static void output_pmu_data_header (FILE *gcov_file, pmu_data_t *pmu_data);
+static void output_pmu_data (FILE *gcov_file, const source_t *src,
+ const unsigned line_num);
+static void output_load_latency_line (FILE *fp,
+ const gcov_pmu_ll_info_t *ll_info,
+ gcov_pmu_tool_header_t *tool_header);
+static void output_branch_mispredict_line (FILE *fp,
+ const gcov_pmu_brm_info_t *brm_info);
+
extern int main (int, char **);
int
@@ -383,6 +421,15 @@ main (int argc, char **argv)
if (argc - argno > 1)
multiple_files = 1;
+ /* We read pmu profile first because we later filter
+ src:line_numbers for each source. */
+ if (flag_pmu_profile)
+ {
+ if (!pmu_profile_filename)
+ pmu_profile_filename = pmu_profile_default_filename;
+ process_pmu_profile ();
+ }
+
for (; argno != argc; argno++)
process_file (argv[argno]);
@@ -420,6 +467,7 @@ print_usage (int error_p)
fnotice (file, " -b, --branch-probabilities Include branch probabilities in output\n");
fnotice (file, " -c, --branch-counts Given counts of branches taken\n\
rather than percentages\n");
+ fnotice (file, " -m, --pmu-profile Output PMU profile data if available\n");
fnotice (file, " -n, --no-output Do not create an output file\n");
fnotice (file, " -l, --long-file-names Use long output file names for included\n\
source files\n");
@@ -432,6 +480,7 @@ print_usage (int error_p)
applications. It will output a single\n\
.gcov file per .gcda file. No source file\n\
is required.\n");
+ fnotice (file, " -q, --pmu_profile-path Path for PMU profile (default pmuprofile.gcda)\n");
fnotice (file, "\nFor bug reporting instructions, please see:\n%s.\n",
bug_report_url);
exit (status);
@@ -459,6 +508,7 @@ static const struct option options[] =
{ "all-blocks", no_argument, NULL, 'a' },
{ "branch-probabilities", no_argument, NULL, 'b' },
{ "branch-counts", no_argument, NULL, 'c' },
+ { "pmu-profile", no_argument, NULL, 'm' },
{ "no-output", no_argument, NULL, 'n' },
{ "long-file-names", no_argument, NULL, 'l' },
{ "function-summaries", no_argument, NULL, 'f' },
@@ -467,6 +517,7 @@ static const struct option options[] =
{ "object-file", required_argument, NULL, 'o' },
{ "unconditional-branches", no_argument, NULL, 'u' },
{ "intermediate-format", no_argument, NULL, 'i' },
+ { "pmu_profile-path", required_argument, NULL, 'q' },
{ 0, 0, 0, 0 }
};
@@ -477,7 +528,8 @@ process_args (int argc, char **argv)
{
int opt;
- while ((opt = getopt_long (argc, argv, "abcfhilno:puv", options, NULL)) != -1)
+ while ((opt = getopt_long (argc, argv, "abcfhilmno:q:puv", options, NULL))
+ != -1)
{
switch (opt)
{
@@ -499,6 +551,9 @@ process_args (int argc, char **argv)
case 'l':
flag_long_names = 1;
break;
+ case 'm':
+ flag_pmu_profile = 1;
+ break;
case 'n':
flag_gcov_file = 0;
break;
@@ -508,6 +563,9 @@ process_args (int argc, char **argv)
case 'p':
flag_preserve_paths = 1;
break;
+ case 'q':
+ pmu_profile_filename = optarg;
+ break;
case 'u':
flag_unconditional = 1;
break;
@@ -747,6 +805,8 @@ release_structures (void)
{
function_t *fn;
source_t *src;
+ ll_infos_t *ll_infos = &pmu_global_info.ll_infos;
+ brm_infos_t *brm_infos = &pmu_global_info.brm_infos;
while ((src = sources))
{
@@ -754,6 +814,14 @@ release_structures (void)
free (src->name);
free (src->lines);
+ if (src->pmu_data)
+ {
+ if (src->pmu_data->ll_infos.ll_array)
+ free (src->pmu_data->ll_infos.ll_array);
+ if (src->pmu_data->brm_infos.brm_array)
+ free (src->pmu_data->brm_infos.brm_array);
+ free (src->pmu_data);
+ }
}
while ((fn = functions))
@@ -775,6 +843,42 @@ release_structures (void)
free (fn->blocks);
free (fn->counts);
}
+
+ /* Cleanup PMU load latency info. */
+ if (ll_infos->ll_count)
+ {
+ unsigned i;
+
+ /* delete each element */
+ for (i = 0; i < ll_infos->ll_count; ++i)
+ {
+ if (ll_infos->ll_array[i]->filename)
+ XDELETE (ll_infos->ll_array[i]->filename);
+ XDELETE (ll_infos->ll_array[i]);
+ }
+ /* delete the array itself */
+ XDELETE (ll_infos->ll_array);
+ ll_infos->ll_array = NULL;
+ ll_infos->ll_count = 0;
+ }
+
+ /* Cleanup PMU branch mispredict info. */
+ if (brm_infos->brm_count)
+ {
+ unsigned i;
+
+ /* delete each element */
+ for (i = 0; i < brm_infos->brm_count; ++i)
+ {
+ if (brm_infos->brm_array[i]->filename)
+ XDELETE (brm_infos->brm_array[i]->filename);
+ XDELETE (brm_infos->brm_array[i]);
+ }
+ /* delete the array itself */
+ XDELETE (brm_infos->brm_array);
+ brm_infos->brm_array = NULL;
+ brm_infos->brm_count = 0;
+ }
}
/* Generate the names of the graph and data files. If OBJECT_DIRECTORY
@@ -871,6 +975,7 @@ find_source (const char *file_name)
src->coverage.name = src->name;
src->index = source_index++;
src->next = sources;
+ src->pmu_data = 0;
sources = src;
if (!stat (file_name, &status))
@@ -1792,6 +1897,148 @@ add_line_counts (coverage_t *coverage, function_t *fn)
fnotice (stderr, "%s:no lines for '%s'\n", bbg_file_name, fn->name);
}
+/* Filter PMU profile global data for lines for SRC. Save PMU info
+ matching the source file and sort them by line number for later
+ line by line processing. */
+
+static void
+filter_pmu_data_lines (source_t *src)
+{
+ unsigned i;
+ int changed;
+ ll_infos_t *ll_infos; /* load latency information for this source */
+ brm_infos_t *brm_infos; /* branch mispredict information for this source */
+
+ if (pmu_global_info.ll_infos.ll_count == 0 &&
+ pmu_global_info.brm_infos.brm_count == 0)
+ /* If there are no global entries, there is nothing to filter. */
+ return;
+
+ src->pmu_data = XCNEW (pmu_data_t);
+ ll_infos = &src->pmu_data->ll_infos;
+ brm_infos = &src->pmu_data->brm_infos;
+ ll_infos->pmu_tool_header = pmu_global_info.ll_infos.pmu_tool_header;
+ brm_infos->pmu_tool_header = pmu_global_info.brm_infos.pmu_tool_header;
+ ll_infos->ll_array = 0;
+ brm_infos->brm_array = 0;
+
+ /* Go over all the load latency entries and save the ones
+ corresponding to this source file. */
+ for (i = 0; i < pmu_global_info.ll_infos.ll_count; ++i)
+ {
+ gcov_pmu_ll_info_t *ll_info = pmu_global_info.ll_infos.ll_array[i];
+ if (0 == strcmp (src->name, ll_info->filename))
+ {
+ if (!ll_infos->ll_array)
+ {
+ ll_infos->ll_count = 0;
+ ll_infos->alloc_ll_count = 64;
+ ll_infos->ll_array = XCNEWVEC (gcov_pmu_ll_info_t *,
+ ll_infos->alloc_ll_count);
+ }
+ /* Found a matching entry, save it. */
+ ll_infos->ll_count++;
+ if (ll_infos->ll_count >= ll_infos->alloc_ll_count)
+ {
+ /* need to realloc */
+ ll_infos->ll_array = (gcov_pmu_ll_info_t **)
+ xrealloc (ll_infos->ll_array, 2 * ll_infos->alloc_ll_count);
+ if (ll_infos->ll_array == NULL) {
+ fprintf (stderr, "Cannot allocate memory for load latency.\n");
+ return;
+ }
+ }
+ ll_infos->ll_array[ll_infos->ll_count - 1] = ll_info;
+ }
+ }
+
+ /* Go over all the branch mispredict entries and save the ones
+ corresponding to this source file. */
+ for (i = 0; i < pmu_global_info.brm_infos.brm_count; ++i)
+ {
+ gcov_pmu_brm_info_t *brm_info = pmu_global_info.brm_infos.brm_array[i];
+ if (0 == strcmp (src->name, brm_info->filename))
+ {
+ if (!brm_infos->brm_array)
+ {
+ brm_infos->brm_count = 0;
+ brm_infos->alloc_brm_count = 64;
+ brm_infos->brm_array = XCNEWVEC (gcov_pmu_brm_info_t *,
+ brm_infos->alloc_brm_count);
+ }
+ /* Found a matching entry, save it. */
+ brm_infos->brm_count++;
+ if (brm_infos->brm_count >= brm_infos->alloc_brm_count)
+ {
+ /* need to realloc */
+ brm_infos->brm_array = (gcov_pmu_brm_info_t **)
+ xrealloc (brm_infos->brm_array, 2 * brm_infos->alloc_brm_count);
+ if (brm_infos->brm_array == NULL) {
+ fprintf (stderr, "Cannot allocate memory for load latency.\n");
+ return;
+ }
+ }
+ brm_infos->brm_array[brm_infos->brm_count - 1] = brm_info;
+ }
+ }
+
+ /* Sort the load latency data according to the line numbers because
+ we later iterate over sources in line number order. Normally we
+ expect the PMU tool to provide sorted data, but a few entries can
+ be out of order. Thus we use a very simple bubble sort here. */
+ if (ll_infos->ll_count > 1)
+ {
+ changed = 1;
+ while (changed)
+ {
+ changed = 0;
+ for (i = 0; i < ll_infos->ll_count - 1; ++i)
+ {
+ gcov_pmu_ll_info_t *item1 = ll_infos->ll_array[i];
+ gcov_pmu_ll_info_t *item2 = ll_infos->ll_array[i+1];
+ if (item1->line > item2->line)
+ {
+ /* swap */
+ gcov_pmu_ll_info_t *tmp = ll_infos->ll_array[i];
+ ll_infos->ll_array[i] = ll_infos->ll_array[i+1];
+ ll_infos->ll_array[i+1] = tmp;
+ changed = 1;
+ }
+ }
+ }
+ }
+
+ /* Similarly, sort branch mispredict info as well. */
+ if (brm_infos->brm_count > 1)
+ {
+ changed = 1;
+ while (changed)
+ {
+ changed = 0;
+ for (i = 0; i < brm_infos->brm_count - 1; ++i)
+ {
+ gcov_pmu_brm_info_t *item1 = brm_infos->brm_array[i];
+ gcov_pmu_brm_info_t *item2 = brm_infos->brm_array[i+1];
+ if (item1->line > item2->line)
+ {
+ /* swap */
+ gcov_pmu_brm_info_t *tmp = brm_infos->brm_array[i];
+ brm_infos->brm_array[i] = brm_infos->brm_array[i+1];
+ brm_infos->brm_array[i+1] = tmp;
+ changed = 1;
+ }
+ }
+ }
+ }
+
+ /* If no matching PMU info was found, relase the structures. */
+ if (!brm_infos->brm_array && !ll_infos->ll_array)
+ {
+ free (src->pmu_data);
+ src->pmu_data = 0;
+ }
+}
+
/* Accumulate the line counts of a file. */
static void
@@ -1801,6 +2048,10 @@ accumulate_line_counts (source_t *src)
function_t *fn, *fn_p, *fn_n;
unsigned ix;
+ if (flag_pmu_profile)
+ /* Filter PMU profile by source files and save into matching line(s). */
+ filter_pmu_data_lines (src);
+
/* Reverse the function order. */
for (fn = src->functions, fn_p = NULL; fn;
fn_p = fn, fn = fn_n)
@@ -2048,6 +2299,9 @@ output_lines (FILE *gcov_file, const source_t *src)
else if (src->file_time == 0)
fprintf (gcov_file, "%9s:%5d:Source is newer than graph\n", "-", 0);
+ if (src->pmu_data)
+ output_pmu_data_header (gcov_file, src->pmu_data);
+
if (flag_branches)
fn = src->functions;
@@ -2125,6 +2379,10 @@ output_lines (FILE *gcov_file, const source_t *src)
for (ix = 0, arc = line->u.branches; arc; arc = arc->line_next)
ix += output_branch_count (gcov_file, ix, arc);
}
+
+ /* Output PMU profile info if available. */
+ if (flag_pmu_profile)
+ output_pmu_data (gcov_file, src, line_num);
}
/* Handle all remaining source lines. There may be lines after the
@@ -2148,3 +2406,244 @@ output_lines (FILE *gcov_file, const source_t *src)
if (source_file)
fclose (source_file);
}
+
+/* Print an explanatory header for PMU_DATA into GCOV_FILE. */
+
+static void
+output_pmu_data_header (FILE *gcov_file, pmu_data_t *pmu_data)
+{
+ /* Print header for the applicable PMU events. */
+ fprintf (gcov_file, "%9s:%5d\n", "-", 0);
+ if (pmu_data->ll_infos.ll_count)
+ {
+ char *text = pmu_data->ll_infos.pmu_tool_header->column_description;
+ char c;
+ fprintf (gcov_file, "%9s:%5u: %s", "PMU_LL", 0,
+ pmu_data->ll_infos.pmu_tool_header->column_header);
+ /* The column description is multiline text and we want to print
+ each line separately after formatting it. */
+ fprintf (gcov_file, "%9s:%5u: ", "PMU_LL", 0);
+ while ((c = *text++))
+ {
+ fprintf (gcov_file, "%c", c);
+ /* Do not print a new header on trailing newline. */
+ if (c == '\n' && text[1])
+ fprintf (gcov_file, "%9s:%5u: ", "PMU_LL", 0);
+ }
+ fprintf (gcov_file, "%9s:%5d\n", "-", 0);
+ }
+
+ if (pmu_data->brm_infos.brm_count)
+ {
+
+ fprintf (gcov_file, "%9s:%5d:PMU BRM: line: %s %s %s\n",
+ "-", 0, "count", "self", "address");
+ fprintf (gcov_file, "%9s:%5d: "
+ "count: number of branch mispredicts sampled at this address\n",
+ "-", 0);
+ fprintf (gcov_file, "%9s:%5d: "
+ "self: branch mispredicts as percentage of the entire program\n",
+ "-", 0);
+ fprintf (gcov_file, "%9s:%5d\n", "-", 0);
+ }
+}
+
+/* Output pmu data corresponding to SRC and LINE_NUM into GCOV_FILE. */
+
+static void
+output_pmu_data (FILE *gcov_file, const source_t *src, const unsigned line_num)
+{
+ unsigned i;
+ ll_infos_t *ll_infos;
+ brm_infos_t *brm_infos;
+ gcov_pmu_tool_header_t *tool_header;
+
+ if (!src->pmu_data)
+ return;
+
+ ll_infos = &src->pmu_data->ll_infos;
+ brm_infos = &src->pmu_data->brm_infos;
+
+ if (ll_infos->ll_array)
+ {
+ tool_header = src->pmu_data->ll_infos.pmu_tool_header;
+
+ /* Search PMU load latency data for the matching line
+ numbers. There could be multiple entries with the same line
+ number. We use the fact that line numbers are sorted in
+ ll_array. */
+ for (i = 0; i < ll_infos->ll_count &&
+ ll_infos->ll_array[i]->line <= line_num; ++i)
+ {
+ gcov_pmu_ll_info_t *ll_info = ll_infos->ll_array[i];
+ if (ll_info->line == line_num)
+ output_load_latency_line (gcov_file, ll_info, tool_header);
+ }
+ }
+
+ if (brm_infos->brm_array)
+ {
+ tool_header = src->pmu_data->brm_infos.pmu_tool_header;
+
+ /* Search PMU branch mispredict data for the matching line
+ numbers. There could be multiple entries with the same line
+ number. We use the fact that line numbers are sorted in
+ brm_array. */
+ for (i = 0; i < brm_infos->brm_count &&
+ brm_infos->brm_array[i]->line <= line_num; ++i)
+ {
+ gcov_pmu_brm_info_t *brm_info = brm_infos->brm_array[i];
+ if (brm_info->line == line_num)
+ output_branch_mispredict_line (gcov_file, brm_info);
+ }
+ }
+}
+
+
+/* Output formatted load latency info pointed to by LL_INFO into the
+ open file FP. TOOL_HEADER contains additional explanation of
+ fields. */
+
+static void
+output_load_latency_line (FILE *fp, const gcov_pmu_ll_info_t *ll_info,
+ gcov_pmu_tool_header_t *tool_header ATTRIBUTE_UNUSED)
+{
+ fprintf (fp, "%9s:%5u: ", "PMU_LL", ll_info->line);
+ fprintf (fp, " %u %.2f%% %.2f%% %.2f%% %.2f%% %.2f%% %.2f%% %.2f%% "
+ "%.2f%% %.2f%% " HOST_WIDEST_INT_PRINT_HEX "\n",
+ ll_info->counts,
+ convert_unsigned_to_pct (ll_info->self),
+ convert_unsigned_to_pct (ll_info->cum),
+ convert_unsigned_to_pct (ll_info->lt_10),
+ convert_unsigned_to_pct (ll_info->lt_32),
+ convert_unsigned_to_pct (ll_info->lt_64),
+ convert_unsigned_to_pct (ll_info->lt_256),
+ convert_unsigned_to_pct (ll_info->lt_1024),
+ convert_unsigned_to_pct (ll_info->gt_1024),
+ convert_unsigned_to_pct (ll_info->wself),
+ ll_info->code_addr);
+}
+
+
+/* Output formatted branch mispredict info pointed to by BRM_INFO into
+ the open file FP. */
+
+static void
+output_branch_mispredict_line (FILE *fp,
+ const gcov_pmu_brm_info_t *ll_info)
+{
+ fprintf (fp, "%9s:%5u: count: %u self: %.2f%% addr: "
+ HOST_WIDEST_INT_PRINT_HEX "\n",
+ "PMU BRM",
+ ll_info->line,
+ ll_info->counts,
+ convert_unsigned_to_pct (ll_info->self),
+ ll_info->code_addr);
+}
+
+/* Read in the PMU profile information from the global PMU profile file. */
+
+static void process_pmu_profile (void)
+{
+ unsigned tag;
+ unsigned version;
+ int error = 0;
+ ll_infos_t *ll_infos = &pmu_global_info.ll_infos;
+ brm_infos_t *brm_infos = &pmu_global_info.brm_infos;
+
+ /* Construct path for pmuprofile.gcda filename. */
+ create_file_names (pmu_profile_filename);
+ if (!gcov_open (da_file_name, 1))
+ {
+ fnotice (stderr, "%s:cannot open pmu profile file\n",
+ pmu_profile_filename);
+ return;
+ }
+ if (!gcov_magic (gcov_read_unsigned (), GCOV_DATA_MAGIC))
+ {
+ fnotice (stderr, "%s:not a gcov data file\n", da_file_name);
+ cleanup:;
+ gcov_close ();
+ return;
+ }
+ version = gcov_read_unsigned ();
+ if (version != GCOV_VERSION)
+ {
+ char v[4], e[4];
+
+ GCOV_UNSIGNED2STRING (v, version);
+ GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
+ fnotice (stderr, "%s:version '%.4s', prefer version '%.4s'\n",
+ da_file_name, v, e);
+ }
+ /* read stamp */
+ tag = gcov_read_unsigned ();
+
+ /* Initialize PMU data fields. */
+ ll_infos->ll_count = 0;
+ ll_infos->alloc_ll_count = 64;
+ ll_infos->ll_array = XCNEWVEC (gcov_pmu_ll_info_t *,
+ ll_infos->alloc_ll_count);
+ brm_infos->brm_count = 0;
+ brm_infos->alloc_brm_count = 64;
+ brm_infos->brm_array = XCNEWVEC (gcov_pmu_brm_info_t *,
+ brm_infos->alloc_brm_count);
+
+ while ((tag = gcov_read_unsigned ()))
+ {
+ unsigned length = gcov_read_unsigned ();
+ unsigned long base = gcov_position ();
+
+ if (tag == GCOV_TAG_PMU_LOAD_LATENCY_INFO)
+ {
+ gcov_pmu_ll_info_t *ll_info = XCNEW (gcov_pmu_ll_info_t);
+ gcov_read_pmu_load_latency_info (ll_info, length);
+ ll_infos->ll_count++;
+ if (ll_infos->ll_count >= ll_infos->alloc_ll_count)
+ {
+ /* need to realloc */
+ ll_infos->ll_array = (gcov_pmu_ll_info_t **)
+ xrealloc (ll_infos->ll_array, 2 * ll_infos->alloc_ll_count);
+ if (ll_infos->ll_array == NULL) {
+ fprintf (stderr, "Cannot allocate memory for load latency.\n");
+ goto cleanup;
+ }
+ }
+ ll_infos->ll_array[ll_infos->ll_count - 1] = ll_info;
+ }
+ else if (tag == GCOV_TAG_PMU_BRANCH_MISPREDICT_INFO)
+ {
+ gcov_pmu_brm_info_t *brm_info = XCNEW (gcov_pmu_brm_info_t);
+ gcov_read_pmu_branch_mispredict_info (brm_info, length);
+ brm_infos->brm_count++;
+ if (brm_infos->brm_count >= brm_infos->alloc_brm_count)
+ {
+ /* need to realloc */
+ brm_infos->brm_array = (gcov_pmu_brm_info_t **)
+ xrealloc (brm_infos->brm_array, 2 * brm_infos->alloc_brm_count);
+ if (brm_infos->brm_array == NULL) {
+ fprintf (stderr, "Cannot allocate memory for load latency.\n");
+ goto cleanup;
+ }
+ }
+ brm_infos->brm_array[brm_infos->brm_count - 1] = brm_info;
+ }
+ else if (tag == GCOV_TAG_PMU_TOOL_HEADER)
+ {
+ gcov_pmu_tool_header_t *tool_header = XCNEW (gcov_pmu_tool_header_t);
+ gcov_read_pmu_tool_header (tool_header, length);
+ ll_infos->pmu_tool_header = tool_header;
+ brm_infos->pmu_tool_header = tool_header;
+ }
+
+ gcov_sync (base, length);
+ if ((error = gcov_is_error ()))
+ {
+ fnotice (stderr, error < 0 ? "%s:overflowed\n" : "%s:corrupted\n",
+ da_file_name);
+ goto cleanup;
+ }
+ }
+
+ gcov_close ();
+}
diff --git a/gcc-4.4.3/gcc/genautomata.c b/gcc-4.4.3/gcc/genautomata.c
index d314b8f22..1d742f4dc 100644
--- a/gcc-4.4.3/gcc/genautomata.c
+++ b/gcc-4.4.3/gcc/genautomata.c
@@ -1,5 +1,5 @@
/* Pipeline hazard description translator.
- Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008
+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009
Free Software Foundation, Inc.
Written by Vladimir Makarov <vmakarov@redhat.com>
@@ -22,21 +22,25 @@ along with GCC; see the file COPYING3. If not see
/* References:
- 1. Detecting pipeline structural hazards quickly. T. Proebsting,
+ 1. The finite state automaton based pipeline hazard recognizer and
+ instruction scheduler in GCC. V. Makarov. Proceedings of GCC
+ summit, 2003.
+
+ 2. Detecting pipeline structural hazards quickly. T. Proebsting,
C. Fraser. Proceedings of ACM SIGPLAN-SIGACT Symposium on
Principles of Programming Languages, pages 280--286, 1994.
This article is a good start point to understand usage of finite
state automata for pipeline hazard recognizers. But I'd
- recommend the 2nd article for more deep understanding.
+ recommend the 1st and 3rd article for more deep understanding.
- 2. Efficient Instruction Scheduling Using Finite State Automata:
+ 3. Efficient Instruction Scheduling Using Finite State Automata:
V. Bala and N. Rubin, Proceedings of MICRO-28. This is the best
article about usage of finite state automata for pipeline hazard
recognizers.
- The current implementation is different from the 2nd article in the
- following:
+ The current implementation is described in the 1st article and it
+ is different from the 3rd article in the following:
1. New operator `|' (alternative) is permitted in functional unit
reservation which can be treated deterministically and
@@ -463,7 +467,10 @@ struct insn_reserv_decl
insn. */
int insn_num;
/* The following field value is list of bypasses in which given insn
- is output insn. */
+ is output insn. Bypasses with the same input insn stay one after
+ another in the list in the same order as their occurrences in the
+ description but the bypass without a guard stays always the last
+ in a row of bypasses with the same input insn. */
struct bypass_decl *bypass_list;
/* The following fields are defined by automaton generator. */
@@ -2367,18 +2374,67 @@ add_presence_absence (unit_set_el_t dest_list,
}
-/* The function searches for bypass with given IN_INSN_RESERV in given
- BYPASS_LIST. */
-static struct bypass_decl *
-find_bypass (struct bypass_decl *bypass_list,
- struct insn_reserv_decl *in_insn_reserv)
+/* The function inserts BYPASS in the list of bypasses of the
+ corresponding output insn. The order of bypasses in the list is
+ decribed in a comment for member `bypass_list' (see above). If
+ there is already the same bypass in the list the function reports
+ this and does nothing. */
+static void
+insert_bypass (struct bypass_decl *bypass)
{
- struct bypass_decl *bypass;
-
- for (bypass = bypass_list; bypass != NULL; bypass = bypass->next)
- if (bypass->in_insn_reserv == in_insn_reserv)
- break;
- return bypass;
+ struct bypass_decl *curr, *last;
+ struct insn_reserv_decl *out_insn_reserv = bypass->out_insn_reserv;
+ struct insn_reserv_decl *in_insn_reserv = bypass->in_insn_reserv;
+
+ for (curr = out_insn_reserv->bypass_list, last = NULL;
+ curr != NULL;
+ last = curr, curr = curr->next)
+ if (curr->in_insn_reserv == in_insn_reserv)
+ {
+ if ((bypass->bypass_guard_name != NULL
+ && curr->bypass_guard_name != NULL
+ && ! strcmp (bypass->bypass_guard_name, curr->bypass_guard_name))
+ || bypass->bypass_guard_name == curr->bypass_guard_name)
+ {
+ if (bypass->bypass_guard_name == NULL)
+ {
+ if (!w_flag)
+ error ("the same bypass `%s - %s' is already defined",
+ bypass->out_insn_name, bypass->in_insn_name);
+ else
+ warning (0, "the same bypass `%s - %s' is already defined",
+ bypass->out_insn_name, bypass->in_insn_name);
+ }
+ else if (!w_flag)
+ error ("the same bypass `%s - %s' (guard %s) is already defined",
+ bypass->out_insn_name, bypass->in_insn_name,
+ bypass->bypass_guard_name);
+ else
+ warning
+ (0, "the same bypass `%s - %s' (guard %s) is already defined",
+ bypass->out_insn_name, bypass->in_insn_name,
+ bypass->bypass_guard_name);
+ return;
+ }
+ if (curr->bypass_guard_name == NULL)
+ break;
+ if (curr->next == NULL || curr->next->in_insn_reserv != in_insn_reserv)
+ {
+ last = curr;
+ break;
+ }
+
+ }
+ if (last == NULL)
+ {
+ bypass->next = out_insn_reserv->bypass_list;
+ out_insn_reserv->bypass_list = bypass;
+ }
+ else
+ {
+ bypass->next = last->next;
+ last->next = bypass;
+ }
}
/* The function processes pipeline description declarations, checks
@@ -2391,7 +2447,6 @@ process_decls (void)
decl_t decl_in_table;
decl_t out_insn_reserv;
decl_t in_insn_reserv;
- struct bypass_decl *bypass;
int automaton_presence;
int i;
@@ -2514,36 +2569,7 @@ process_decls (void)
= DECL_INSN_RESERV (out_insn_reserv);
DECL_BYPASS (decl)->in_insn_reserv
= DECL_INSN_RESERV (in_insn_reserv);
- bypass
- = find_bypass (DECL_INSN_RESERV (out_insn_reserv)->bypass_list,
- DECL_BYPASS (decl)->in_insn_reserv);
- if (bypass != NULL)
- {
- if (DECL_BYPASS (decl)->latency == bypass->latency)
- {
- if (!w_flag)
- error
- ("the same bypass `%s - %s' is already defined",
- DECL_BYPASS (decl)->out_insn_name,
- DECL_BYPASS (decl)->in_insn_name);
- else
- warning
- (0, "the same bypass `%s - %s' is already defined",
- DECL_BYPASS (decl)->out_insn_name,
- DECL_BYPASS (decl)->in_insn_name);
- }
- else
- error ("bypass `%s - %s' is already defined",
- DECL_BYPASS (decl)->out_insn_name,
- DECL_BYPASS (decl)->in_insn_name);
- }
- else
- {
- DECL_BYPASS (decl)->next
- = DECL_INSN_RESERV (out_insn_reserv)->bypass_list;
- DECL_INSN_RESERV (out_insn_reserv)->bypass_list
- = DECL_BYPASS (decl);
- }
+ insert_bypass (DECL_BYPASS (decl));
}
}
}
@@ -8159,19 +8185,32 @@ output_internal_insn_latency_func (void)
(advance_cycle_insn_decl)->insn_num));
fprintf (output_file, " case %d:\n",
bypass->in_insn_reserv->insn_num);
- if (bypass->bypass_guard_name == NULL)
- fprintf (output_file, " return %d;\n",
- bypass->latency);
- else
+ for (;;)
{
- fprintf (output_file,
- " if (%s (%s, %s))\n",
- bypass->bypass_guard_name, INSN_PARAMETER_NAME,
- INSN2_PARAMETER_NAME);
- fprintf (output_file,
- " return %d;\n break;\n",
- bypass->latency);
+ if (bypass->bypass_guard_name == NULL)
+ {
+ gcc_assert (bypass->next == NULL
+ || (bypass->in_insn_reserv
+ != bypass->next->in_insn_reserv));
+ fprintf (output_file, " return %d;\n",
+ bypass->latency);
+ }
+ else
+ {
+ fprintf (output_file,
+ " if (%s (%s, %s))\n",
+ bypass->bypass_guard_name, INSN_PARAMETER_NAME,
+ INSN2_PARAMETER_NAME);
+ fprintf (output_file, " return %d;\n",
+ bypass->latency);
+ }
+ if (bypass->next == NULL
+ || bypass->in_insn_reserv != bypass->next->in_insn_reserv)
+ break;
+ bypass = bypass->next;
}
+ if (bypass->bypass_guard_name != NULL)
+ fprintf (output_file, " break;\n");
}
fputs (" }\n break;\n", output_file);
}
diff --git a/gcc-4.4.3/gcc/ggc-page.c b/gcc-4.4.3/gcc/ggc-page.c
index 567ea6fb5..2ddb3dc36 100644
--- a/gcc-4.4.3/gcc/ggc-page.c
+++ b/gcc-4.4.3/gcc/ggc-page.c
@@ -2363,3 +2363,9 @@ ggc_pch_read (FILE *f, void *addr)
/* Update the statistics. */
G.allocated = G.allocated_last_gc = offs - (char *)addr;
}
+
+size_t
+ggc_total_allocated (void)
+{
+ return G.bytes_mapped;
+}
diff --git a/gcc-4.4.3/gcc/ggc.h b/gcc-4.4.3/gcc/ggc.h
index e3471e453..f9670ac90 100644
--- a/gcc-4.4.3/gcc/ggc.h
+++ b/gcc-4.4.3/gcc/ggc.h
@@ -328,4 +328,6 @@ extern void *ggc_alloc_zone_stat (size_t, struct alloc_zone * MEM_STAT_DECL);
#endif
+extern size_t ggc_total_allocated (void);
+
#endif
diff --git a/gcc-4.4.3/gcc/ipa-cp.c b/gcc-4.4.3/gcc/ipa-cp.c
index 73e6b52a6..0bc01ef0d 100644
--- a/gcc-4.4.3/gcc/ipa-cp.c
+++ b/gcc-4.4.3/gcc/ipa-cp.c
@@ -228,6 +228,8 @@ ipcp_update_cloned_node (struct cgraph_node *new_node)
for (cs = new_node->callees; cs; cs = cs->next_callee)
{
+ if (!cs->callee->analyzed)
+ continue;
ipa_count_arguments (cs);
ipa_compute_jump_functions (cs);
}
diff --git a/gcc-4.4.3/gcc/ipa-inline.c b/gcc-4.4.3/gcc/ipa-inline.c
index cb1257211..da7ac498d 100644
--- a/gcc-4.4.3/gcc/ipa-inline.c
+++ b/gcc-4.4.3/gcc/ipa-inline.c
@@ -52,7 +52,7 @@ along with GCC; see the file COPYING3. If not see
To mark given call inline, use cgraph_mark_inline function, the
verification is performed by cgraph_default_inline_p and
- cgraph_check_inline_limits.
+ cgraph_check_inline_constraints.
The heuristics implements simple knapsack style algorithm ordering
all functions by their "profitability" (estimated by code size growth)
@@ -145,6 +145,8 @@ along with GCC; see the file COPYING3. If not see
#include "dbgcnt.h"
#include "tree-dump.h"
+#include <math.h>
+
/* Mode incremental inliner operate on:
In ALWAYS_INLINE only functions marked
@@ -272,28 +274,6 @@ inline_summary (struct cgraph_node *node)
return &node->local.inline_summary;
}
-/* Return true if NODE is a hot function. */
-
-static bool
-hot_function_p (struct cgraph_node *node)
-{
- struct cgraph_edge *edge;
-
- if (node->local.inline_summary.self_hot_insns > 0)
- return true;
-
- for (edge = node->callees; edge; edge = edge->next_callee)
- if (cgraph_maybe_hot_edge_p (edge))
- return true;
-
- for (edge = node->callers; edge; edge = edge->next_caller)
- if (cgraph_maybe_hot_edge_p (edge))
- return true;
-
- return false;
-}
-
-
/* Return the pointer to the list of hot components for NODE. Global
array NODE_HOT_COMPONENT_LIST is resized as necessary for new nodes
with uid's that exceed the bounds of the current array. This may
@@ -1046,48 +1026,107 @@ cgraph_mark_inline (struct cgraph_edge *edge)
return edge;
}
-/* Estimate the growth caused by inlining NODE into all callees. */
+/* Estimate the growth caused by inlining NODE into all callees.
+ Return value is the average expected growth per callsite. */
static int
cgraph_estimate_growth (struct cgraph_node *node)
{
- int growth = 0;
+ int growth = 0, ncalls = 0;
struct cgraph_edge *e;
bool self_recursive = false;
- if (node->global.estimated_growth != INT_MIN)
- return node->global.estimated_growth;
+ if (node->global.estimated_average_growth != INT_MIN)
+ return node->global.estimated_average_growth;
for (e = node->callers; e; e = e->next_caller)
{
if (e->caller == node)
self_recursive = true;
if (e->inline_failed)
- growth += (cgraph_estimate_size_after_inlining (1, e->caller, node)
- - e->caller->global.insns);
+ {
+ growth += (cgraph_estimate_size_after_inlining (1, e->caller, node)
+ - e->caller->global.insns);
+ ncalls++;
+ }
}
/* ??? Wrong for non-trivially self recursive functions or cases where
we decide to not inline for different reasons, but it is not big deal
as in that case we will keep the body around, but we will also avoid
some inlining. */
- if (!node->needed && !DECL_EXTERNAL (node->decl) && !self_recursive)
- growth -= node->global.insns;
+ if (!self_recursive)
+ {
+ int emitted_size = (node->global.insns
+ + PARAM_VALUE(PARAM_INLINE_FUNCTION_SIZE_ADJUSTMENT));
+ if (!node->needed && !DECL_EXTERNAL (node->decl))
+ growth -= emitted_size;
+ else if (node->address_taken)
+ growth -= ((100.0
+ - PARAM_VALUE (PARAM_INLINE_ADDRESS_TAKEN_FUNCTION_EMIT_PROBABILITY))
+ * emitted_size) / 100;
+ else
+ growth -= ((100.0
+ - PARAM_VALUE (PARAM_INLINE_ADDRESS_NOT_TAKEN_FUNCTION_EMIT_PROBABILITY))
+ * emitted_size) / 100;
+ }
- node->global.estimated_growth = growth;
+ if (ncalls > 0)
+ /* If growth before averaging is less than zero, we'd like the
+ average to be less than zero because some heuristics cue off
+ this less-than-zero growth condition, so subtract NCALLS - 1 to
+ ensure that -1/NCALLS rounds down to -1. */
+ growth = (growth - (ncalls - 1)) / ncalls;
+