summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2012-11-06 09:38:38 -0800
committerRichard Henderson <rth@redhat.com>2012-11-06 09:38:38 -0800
commit5347d82b89a27d541b39439aed0d304426d8b353 (patch)
tree0274b6cb0ba20dc1921b76214bfc54e6495820e7
parentcdbe84c78a7a5fb14e7d89200559237335f2a860 (diff)
parent698dd25b854c589f62180a0324806e8899c76bcd (diff)
downloadgcc-5347d82b89a27d541b39439aed0d304426d8b353.tar.gz
Merge remote-tracking branch 'trunk' into aldyh/uninst
-rw-r--r--gcc/ChangeLog236
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/ada/ChangeLog388
-rw-r--r--gcc/ada/adaint.c15
-rw-r--r--gcc/ada/adaint.h6
-rw-r--r--gcc/ada/ali.adb13
-rw-r--r--gcc/ada/atree.adb14
-rw-r--r--gcc/ada/atree.ads33
-rw-r--r--gcc/ada/bindgen.adb96
-rw-r--r--gcc/ada/checks.adb315
-rw-r--r--gcc/ada/checks.ads45
-rw-r--r--gcc/ada/einfo.adb17
-rw-r--r--gcc/ada/einfo.ads9
-rw-r--r--gcc/ada/err_vars.ads26
-rw-r--r--gcc/ada/errno.c2
-rw-r--r--gcc/ada/errout.adb15
-rw-r--r--gcc/ada/errout.ads20
-rw-r--r--gcc/ada/erroutc.adb3
-rw-r--r--gcc/ada/erroutc.ads2
-rw-r--r--gcc/ada/errutil.adb3
-rw-r--r--gcc/ada/errutil.ads6
-rw-r--r--gcc/ada/eval_fat.adb39
-rw-r--r--gcc/ada/eval_fat.ads16
-rw-r--r--gcc/ada/exp_attr.adb40
-rw-r--r--gcc/ada/exp_ch13.adb1
-rw-r--r--gcc/ada/exp_ch2.adb15
-rw-r--r--gcc/ada/exp_ch3.adb20
-rw-r--r--gcc/ada/exp_ch4.adb56
-rw-r--r--gcc/ada/exp_ch5.adb343
-rw-r--r--gcc/ada/exp_ch6.adb1
-rw-r--r--gcc/ada/exp_ch9.adb45
-rw-r--r--gcc/ada/exp_dbug.adb14
-rw-r--r--gcc/ada/exp_dist.adb1
-rw-r--r--gcc/ada/exp_prag.adb399
-rw-r--r--gcc/ada/exp_util.adb8
-rw-r--r--gcc/ada/exp_vfpt.adb214
-rw-r--r--gcc/ada/exp_vfpt.ads13
-rw-r--r--gcc/ada/expander.adb1
-rw-r--r--gcc/ada/fe.h10
-rw-r--r--gcc/ada/fmap.adb2
-rw-r--r--gcc/ada/fmap.ads2
-rw-r--r--gcc/ada/gcc-interface/Make-lang.in527
-rw-r--r--gcc/ada/gcc-interface/Makefile.in67
-rw-r--r--gcc/ada/gcc-interface/trans.c54
-rw-r--r--gcc/ada/gnat1drv.adb72
-rw-r--r--gcc/ada/gnat_ugn.texi177
-rw-r--r--gcc/ada/gprep.adb6
-rw-r--r--gcc/ada/gsocket.h2
-rw-r--r--gcc/ada/impunit.adb17
-rw-r--r--gcc/ada/init.c4
-rw-r--r--gcc/ada/makeutl.adb1
-rw-r--r--gcc/ada/par-ch4.adb43
-rw-r--r--gcc/ada/par-prag.adb1
-rw-r--r--gcc/ada/par_sco.adb27
-rw-r--r--gcc/ada/prepcomp.adb1
-rw-r--r--gcc/ada/prj-part.adb3
-rw-r--r--gcc/ada/prj-proc.adb5
-rw-r--r--gcc/ada/projects.texi10
-rw-r--r--gcc/ada/rtsfind.ads20
-rw-r--r--gcc/ada/s-bignum.adb55
-rw-r--r--gcc/ada/s-oscons-tmplt.c7
-rw-r--r--gcc/ada/s-osinte-android.adb118
-rw-r--r--gcc/ada/s-osinte-android.ads643
-rw-r--r--gcc/ada/s-tarest.adb123
-rw-r--r--gcc/ada/s-tarest.ads64
-rw-r--r--gcc/ada/s-tposen.ads1
-rw-r--r--gcc/ada/scng.adb2
-rw-r--r--gcc/ada/sdefault.ads2
-rw-r--r--gcc/ada/sem.adb64
-rw-r--r--gcc/ada/sem_attr.adb255
-rw-r--r--gcc/ada/sem_ch10.adb5
-rw-r--r--gcc/ada/sem_ch13.adb22
-rw-r--r--gcc/ada/sem_ch2.adb3
-rw-r--r--gcc/ada/sem_ch3.adb1
-rw-r--r--gcc/ada/sem_ch4.adb10
-rw-r--r--gcc/ada/sem_ch5.adb9
-rw-r--r--gcc/ada/sem_ch8.adb19
-rw-r--r--gcc/ada/sem_ch9.adb67
-rw-r--r--gcc/ada/sem_dim.adb2
-rw-r--r--gcc/ada/sem_elab.adb1
-rw-r--r--gcc/ada/sem_eval.adb87
-rw-r--r--gcc/ada/sem_intr.adb4
-rw-r--r--gcc/ada/sem_prag.adb183
-rw-r--r--gcc/ada/sem_res.adb96
-rw-r--r--gcc/ada/sem_type.adb7
-rw-r--r--gcc/ada/sem_util.adb22
-rw-r--r--gcc/ada/sem_util.ads8
-rw-r--r--gcc/ada/sem_warn.adb3
-rw-r--r--gcc/ada/snames.ads-tmpl13
-rw-r--r--gcc/ada/stylesw.adb2
-rw-r--r--gcc/ada/switch-c.adb17
-rw-r--r--gcc/ada/sysdep.c49
-rw-r--r--gcc/ada/terminals.c3
-rw-r--r--gcc/ada/types.ads59
-rw-r--r--gcc/ada/uintp.adb11
-rw-r--r--gcc/ada/uintp.ads2
-rw-r--r--gcc/ada/vms_data.ads5
-rw-r--r--gcc/ada/xoscons.adb259
-rw-r--r--gcc/ada/xutil.adb4
-rw-r--r--gcc/ada/xutil.ads2
-rw-r--r--gcc/cfgloop.h1
-rw-r--r--gcc/cfgloopanal.c33
-rw-r--r--gcc/cgraph.c138
-rw-r--r--gcc/cgraph.h46
-rw-r--r--gcc/cgraphunit.c37
-rw-r--r--gcc/config/epiphany/epiphany.c31
-rw-r--r--gcc/config/i386/i386-protos.h7
-rw-r--r--gcc/config/i386/i386.c1792
-rw-r--r--gcc/config/i386/i386.h60
-rw-r--r--gcc/config/i386/i386.md190
-rw-r--r--gcc/config/i386/predicates.md17
-rw-r--r--gcc/config/i386/sse.md328
-rw-r--r--gcc/config/i386/sync.md8
-rw-r--r--gcc/config/sh/sh.c30
-rw-r--r--gcc/config/sh/sh.md217
-rw-r--r--gcc/cp/ChangeLog19
-rw-r--r--gcc/cp/call.c106
-rw-r--r--gcc/cp/class.c105
-rw-r--r--gcc/cp/decl.c46
-rw-r--r--gcc/cp/decl2.c4
-rw-r--r--gcc/doc/invoke.texi3
-rw-r--r--gcc/doc/tm.texi31
-rw-r--r--gcc/doc/tm.texi.in31
-rw-r--r--gcc/final.c43
-rw-r--r--gcc/fortran/ChangeLog8
-rw-r--r--gcc/fortran/target-memory.c4
-rw-r--r--gcc/fortran/trans-intrinsic.c77
-rw-r--r--gcc/gimple-fold.c9
-rw-r--r--gcc/ipa-inline.c31
-rw-r--r--gcc/ipa-pure-const.c13
-rw-r--r--gcc/mode-switching.c17
-rw-r--r--gcc/params.def5
-rw-r--r--gcc/recog.c2
-rw-r--r--gcc/target.def41
-rw-r--r--gcc/testsuite/ChangeLog71
-rw-r--r--gcc/testsuite/g++.dg/mv1.C130
-rw-r--r--gcc/testsuite/g++.dg/mv2.C118
-rw-r--r--gcc/testsuite/g++.dg/mv3.C36
-rw-r--r--gcc/testsuite/g++.dg/mv4.C23
-rw-r--r--gcc/testsuite/g++.dg/mv5.C24
-rw-r--r--gcc/testsuite/g++.dg/mv6.C25
-rw-r--r--gcc/testsuite/g++.dg/torture/20121105-1.C42
-rw-r--r--gcc/testsuite/gcc.dg/const-uniq-1.c11
-rw-r--r--gcc/testsuite/gcc.dg/torture/fp-compare.c23
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr41993.c7
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr53922.c1
-rw-r--r--gcc/testsuite/gcc.dg/tree-prof/unroll-1.c1
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/cunroll-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/loop-1.c9
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/loop-23.c23
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-vzeroupper-10.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-vzeroupper-11.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-vzeroupper-12.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-vzeroupper-19.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-vzeroupper-27.c26
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-vzeroupper-5.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-vzeroupper-8.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-vzeroupper-9.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/l_fma_double_1.c16
-rw-r--r--gcc/testsuite/gcc.target/i386/l_fma_double_2.c8
-rw-r--r--gcc/testsuite/gcc.target/i386/l_fma_double_3.c16
-rw-r--r--gcc/testsuite/gcc.target/i386/l_fma_double_4.c8
-rw-r--r--gcc/testsuite/gcc.target/i386/l_fma_double_5.c8
-rw-r--r--gcc/testsuite/gcc.target/i386/l_fma_double_6.c8
-rw-r--r--gcc/testsuite/gcc.target/i386/l_fma_float_1.c16
-rw-r--r--gcc/testsuite/gcc.target/i386/l_fma_float_2.c8
-rw-r--r--gcc/testsuite/gcc.target/i386/l_fma_float_3.c16
-rw-r--r--gcc/testsuite/gcc.target/i386/l_fma_float_4.c8
-rw-r--r--gcc/testsuite/gcc.target/i386/l_fma_float_5.c8
-rw-r--r--gcc/testsuite/gcc.target/i386/l_fma_float_6.c8
-rw-r--r--gcc/testsuite/gcc.target/sh/pr54089-8.c203
-rw-r--r--gcc/testsuite/gcc.target/sh/pr54089-9.c63
-rw-r--r--gcc/testsuite/gfortran.dg/transfer_class_1.f9016
-rw-r--r--gcc/testsuite/gfortran.dg/transfer_class_2.f9045
-rw-r--r--gcc/tree-ssa-loop-ivcanon.c171
-rw-r--r--gcc/tree-vect-loop-manip.c17
-rw-r--r--gcc/tree-vect-loop.c25
-rw-r--r--gcc/tree.h10
-rw-r--r--libada/ChangeLog13
-rw-r--r--libada/Makefile.in3
-rw-r--r--libstdc++-v3/ChangeLog79
-rw-r--r--libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver9
-rw-r--r--libstdc++-v3/include/bits/atomic_base.h11
-rw-r--r--libstdc++-v3/include/bits/random.tcc1
-rw-r--r--libstdc++-v3/include/debug/formatter.h3
-rw-r--r--libstdc++-v3/include/debug/forward_list31
-rw-r--r--libstdc++-v3/include/debug/macros.h5
-rw-r--r--libstdc++-v3/include/debug/vector4
-rw-r--r--libstdc++-v3/include/ext/throw_allocator.h45
-rw-r--r--libstdc++-v3/include/profile/deque23
-rw-r--r--libstdc++-v3/include/profile/forward_list21
-rw-r--r--libstdc++-v3/include/profile/list28
-rw-r--r--libstdc++-v3/include/profile/map.h13
-rw-r--r--libstdc++-v3/include/profile/multimap.h10
-rw-r--r--libstdc++-v3/include/profile/multiset.h12
-rw-r--r--libstdc++-v3/include/profile/set.h14
-rw-r--r--libstdc++-v3/include/profile/vector16
-rw-r--r--libstdc++-v3/include/std/atomic6
-rw-r--r--libstdc++-v3/include/tr2/dynamic_bitset1
-rw-r--r--libstdc++-v3/libsupc++/vec.cc9
-rw-r--r--libstdc++-v3/src/c++11/debug.cc3
-rw-r--r--libstdc++-v3/testsuite/23_containers/deque/requirements/exception/propagation_consistent.cc3
-rw-r--r--libstdc++-v3/testsuite/23_containers/forward_list/allocator/swap.cc17
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_multimap/insert/55028-debug.cc40
-rw-r--r--libstdc++-v3/testsuite/23_containers/vector/allocator/swap.cc19
-rw-r--r--libstdc++-v3/testsuite/26_numerics/random/discard_block_engine/cons/55215.cc58
-rw-r--r--libstdc++-v3/testsuite/26_numerics/random/independent_bits_engine/cons/55215.cc60
-rw-r--r--libstdc++-v3/testsuite/26_numerics/random/linear_congruential_engine/cons/55215.cc58
-rw-r--r--libstdc++-v3/testsuite/26_numerics/random/mersenne_twister_engine/cons/55215.cc58
-rw-r--r--libstdc++-v3/testsuite/26_numerics/random/shuffle_order_engine/cons/55215.cc58
-rw-r--r--libstdc++-v3/testsuite/26_numerics/random/subtract_with_carry_engine/cons/55215.cc58
-rw-r--r--libstdc++-v3/testsuite/util/exception/safety.h239
-rw-r--r--libstdc++-v3/testsuite/util/testsuite_container_traits.h14
213 files changed, 9045 insertions, 2645 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b0c4fd1fa26..9b274f88179 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,237 @@
+2012-11-06 Jan Hubicka <jh@suse.cz>
+
+ * ipa-inline.c (compute_uninlined_call_time): Return gcov_type.
+ (compute_inlined_call_time): Watch overflows.
+ (relative_time_benefit): Compute in gcov_type.
+
+2012-11-06 Jan Hubicka <jh@suse.cz>
+
+ * cfgloopanal.c (get_loop_hot_path): New function.
+ * tree-ssa-lop-ivcanon.c (struct loop_size): Add CONSTANT_IV,
+ NUM_NON_PURE_CALLS_ON_HOT_PATH, NUM_PURE_CALLS_ON_HOT_PATH,
+ NUM_BRANCHES_ON_HOT_PATH.
+ (tree_estimate_loop_size): Compute the new values.
+ (try_unroll_loop_completely): Disable unrolling of loops with only
+ calls or too many branches.
+ (tree_unroll_loops_completely): Deal also with outer loops of hot loops.
+ * cfgloop.h (get_loop_hot_path): Declare.
+ * params.def (PARAM_MAX_PEEL_BRANCHES): New parameters.
+ * invoke.texi (max-peel-branches): Document.
+
+2012-11-06 Jan Hubicka <jh@suse.cz>
+
+ * ipa-pure-const.c (check_stmt): Fix debug info formatting.
+
+2012-11-06 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/i386/i386.c (TARGET_INSTANTIATE_DECLS): New define.
+ (ix86_instantiate_decls): New function.
+ (ix86_expand_builtin) <case IX86_BUILTIN_LDMXCSR>: Use SLOT_TEMP
+ stack slot instead of SLOT_VIRTUAL.
+ <case IX86_BUILTIN_STMXCSR>: Ditto.
+ (assign_386_stack_local): Do not assert when virtual slot is valid.
+ * config/i386/i386.h (enum ix86_stack_slot): Remove SLOT_VIRTUAL.
+ * config/i386/i386.md (truncdfsf2): Do not use SLOT_VIRTUAL stack slot.
+ (truncxf<mode>2): Ditto.
+ (floatunssi<mode>2): Ditto.
+ (isinf<mode>2): Ditto.
+ * config/i386/sync.md (atomic_load<mode>): Ditto.
+ (atomic_store<mode>): Ditto.
+
+2012-11-06 Jan Hubicka <jh@suse.cz>
+
+ * tree-vect-loop-manip.c (vect_do_peeling_for_loop_bound,
+ vect_do_peeling_for_alignment): Fix loop bound computation.
+ * tree-vect-loop.c (vect_transform_loop): Maintain loop bounds.
+
+2012-11-06 Oleg Endo <olegendo@gcc.gnu.org>
+
+ PR target/54089
+ * config/sh/sh.c (and_xor_ior_costs, addsubcosts): Double the costs for
+ ops larger than SImode.
+ * config/sh/sh.md (rotcl, *rotcl): New insns and splits.
+ (ashldi3_k): Convert to insn_and_split and use new rotcl insn.
+
+2012-11-06 Vladimir Yakovlev <vladimir.b.yakovlev@intel.com>
+
+ * config/i386/i386-protos.h (emit_i387_cw_initialization): Delete.
+ (emit_vzero): Add prototype.
+ (ix86_mode_entry): Likewise.
+ (ix86_mode_exit): Likewise.
+ (ix86_emit_mode_set): Likewise.
+
+ * config/i386/i386.c (typedef struct block_info_def): Delete.
+ (define BLOCK_INFO): Delete.
+ (check_avx256_stores): Add checking for MEM_P.
+ (move_or_delete_vzeroupper_2): Delete.
+ (move_or_delete_vzeroupper_1): Delete.
+ (move_or_delete_vzeroupper): Delete.
+ (ix86_maybe_emit_epilogue_vzeroupper): Delete.
+ (function_pass_avx256_p): Delete.
+ (ix86_function_ok_for_sibcall): Remove sibcall disabling.
+ (nit_cumulative_args): Remove initialization of of avx256 fields of
+ cfun->machine.
+ (ix86_emit_restore_sse_regs_using_mov): Remove vzeroupper generation.
+ (ix86_expand_epilogue): Likewise.
+ (ix86_avx_u128_mode_needed): New.
+ (ix86_i387_mode_needed): Rename from ix86_mode_needed.
+ (ix86_mode_needed): New.
+ (ix86_avx_u128_mode_after): New.
+ (ix86_mode_after): New.
+ (ix86_avx_u128_mode_entry): New.
+ (ix86_mode_entry): New.
+ (ix86_avx_u128_mode_exit): New.
+ (ix86_mode_exit): New.
+ (ix86_emit_mode_set): New.
+ (ix86_expand_call): Delete vzeroupper generation.
+ (ix86_split_call_vzeroupper): Delete.
+ (ix86_init_machine_status): Initialize optimize_mode_switching.
+ (ix86_expand_special_args_builtin): Change.
+ (ix86_reorg): Delete a call of move_or_delete_vzeroupper.
+
+ * config/i386/i386.h (VALID_AVX256_REG_OR_OI_MODE): New.
+ (AVX_U128): New.
+ (avx_u128_state): New.
+ (NUM_MODES_FOR_MODE_SWITCHING): Added AVX_U128_ANY.
+ (MODE_AFTER): New.
+ (MODE_ENTRY): New.
+ (MODE_EXIT): New.
+ (EMIT_MODE_SET): Change.
+ (machine_function): Delete avx256 fields.
+
+ * config/i386/i386.md (UNSPEC_CALL_NEEDS_VZEROUPPER): Delete.
+ (define_insn_and_split "*call_vzeroupper"): Delete.
+ (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"): Delete.
+ (define_insn_and_split "*sibcall_vzeroupper"): Delete.
+ (define_insn_and_split "*call_pop_vzeroupper"): Delete.
+ (define_insn_and_split "*sibcall_pop_vzeroupper"): Delete.
+ (define_insn_and_split "*call_value_vzeroupper"): Delete.
+ (define_insn_and_split "*sibcall_value_vzeroupper"): Delete.
+ (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"): Delete.
+ (define_insn_and_split "*call_value_pop_vzeroupper"): Delete.
+ (define_insn_and_split "*sibcall_value_pop_vzeroupper"): Delete.
+ (define_expand "return"): Remove vzeroupper emitting.
+ (define_expand "simple_return"): Delete.
+
+ * config/i386/predicates.md (vzeroupper_operation): New.
+
+ * config/i386/sse.md (avx_vzeroupper): Change.
+
+2012-11-06 Uros Bizjak <ubizjak@gmail.com>
+ Kaz Kojima <kkojima@gcc.gnu.org>
+
+ PR target/41993
+ * mode-switching.c (create_pre_exit): Set return_copy to
+ last_insn when copy_start is a pseudo reg.
+
+2012-11-06 Andrey Turetskiy <andrey.turetskiy@gmail.com>
+
+ * config/i386/i386.c (bdesc_args): Rename CODE_FOR_avx2_umulhrswv16hi3
+ to CODE_FOR_avx2_pmulhrswv16hi3.
+ * config/i386/predicates.md (const1_operand): Extend for vectors.
+ * config/i386/sse.md (ssse3_avx2): Extend.
+ (ssedoublemode): Ditto.
+ (<sse2_avx2>_uavg<mode>3): Merge avx2_uavgv32qi3, sse2_uavgv16qi3,
+ avx2_uavgv16hi3 and sse2_uavgv8hi3 into one.
+ (*<sse2_avx2>_uavg<mode>3): Merge *avx2_uavgv32qi3, *sse2_uavgv16qi3,
+ *avx2_uavgv16hi3 and *sse2_uavgv8hi3 into one.
+ (PMULHRSW): New.
+ (<ssse3_avx2>_pmulhrsw<mode>3): Merge avx2_umulhrswv16hi3,
+ ssse3_pmulhrswv8hi3 and ssse3_pmulhrswv4hi3 into one.
+ (*avx2_pmulhrswv16hi3): Replace const_vector with const1_operand
+ predicate.
+ (*ssse3_pmulhrswv8hi3): Ditto.
+ (*ssse3_pmulhrswv4hi3): Ditto.
+
+2012-11-06 Joern Rennecke <joern.rennecke@embecosm.com>
+
+ * config/epiphany/epiphany.c (epiphany_address_cost):
+ Use MODE parameter.
+
+2012-11-05 Sriraman Tallam <tmsriram@google.com>
+
+ * doc/tm.texi.in (TARGET_OPTION_FUNCTION_VERSIONS): New hook
+ description.
+ * (TARGET_COMPARE_VERSION_PRIORITY): New hook description.
+ * (TARGET_GET_FUNCTION_VERSIONS_DISPATCHER): New hook description.
+ * (TARGET_GENERATE_VERSION_DISPATCHER_BODY): New hook description.
+ * doc/tm.texi: Regenerate.
+ * target.def (compare_version_priority): New target hook.
+ * (generate_version_dispatcher_body): New target hook.
+ * (get_function_versions_dispatcher): New target hook.
+ * (function_versions): New target hook.
+ * cgraph.c (cgraph_fnver_htab): New htab.
+ (cgraph_fn_ver_htab_hash): New function.
+ (cgraph_fn_ver_htab_eq): New function.
+ (version_info_node): New pointer.
+ (insert_new_cgraph_node_version): New function.
+ (get_cgraph_node_version): New function.
+ (delete_function_version): New function.
+ (record_function_versions): New function.
+ * cgraph.h (cgraph_node): New bitfield dispatcher_function.
+ (cgraph_function_version_info): New struct.
+ (get_cgraph_node_version): New function.
+ (insert_new_cgraph_node_version): New function.
+ (record_function_versions): New function.
+ (delete_function_version): New function.
+ (init_lowered_empty_function): Expose function.
+ * tree.h (DECL_FUNCTION_VERSIONED): New macro.
+ (tree_function_decl): New bit-field versioned_function.
+ * cgraphunit.c (cgraph_analyze_function): Generate body of multiversion
+ function dispatcher.
+ (cgraph_analyze_functions): Analyze dispatcher function.
+ (init_lowered_empty_function): Make non-static. New parameter in_ssa.
+ (assemble_thunk): Add parameter to call to init_lowered_empty_function.
+ * config/i386/i386.c (add_condition_to_bb): New function.
+ (get_builtin_code_for_version): New function.
+ (ix86_compare_version_priority): New function.
+ (feature_compare): New function.
+ (dispatch_function_versions): New function.
+ (ix86_function_versions): New function.
+ (attr_strcmp): New function.
+ (ix86_mangle_function_version_assembler_name): New function.
+ (ix86_mangle_decl_assembler_name): New function.
+ (make_name): New function.
+ (make_dispatcher_decl): New function.
+ (is_function_default_version): New function.
+ (ix86_get_function_versions_dispatcher): New function.
+ (make_attribute): New function.
+ (make_resolver_func): New function.
+ (ix86_generate_version_dispatcher_body): New function.
+ (fold_builtin_cpu): Return integer for cpu builtins.
+ (TARGET_MANGLE_DECL_ASSEMBLER_NAME): New macro.
+ (TARGET_COMPARE_VERSION_PRIORITY): New macro.
+ (TARGET_GENERATE_VERSION_DISPATCHER_BODY): New macro.
+ (TARGET_GET_FUNCTION_VERSIONS_DISPATCHER): New macro.
+ (TARGET_OPTION_FUNCTION_VERSIONS): New macro.
+
+2012-11-05 Joern Rennecke <joern.rennecke@embecosm.com>
+
+ * recog.c (extract_insn): Enabled alternative defaults to 1.
+
+2012-11-05 H.J. Lu <hongjiu.lu@intel.com>
+
+ * config/i386/i386.c (print_reg): Replace REX_INT_REG_P with
+ REX_INT_REGNO_P.
+
+2012-11-05 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR tree-optimization/54986
+ * gimple-fold.c (canonicalize_constructor_val): Strip again all no-op
+ conversions on entry but add them back on exit if needed.
+
+2012-11-05 Andreas Schwab <schwab@linux-m68k.org>
+
+ * final.c (final_scan_insn) [HAVE_cc0]: Handle all comparison
+ codes in non-jump and cmove insn.
+
+2012-11-05 Uros Bizjak <ubizjak@gmail.com>
+ Vladimir Yakovlev <vladimir.b.yakovlev@intel.com>
+
+ * mode-switching.c (create_pre_exit): Force late switching if
+ __builtin_{apply,return} emitted a load that require mode,
+ other than MODE_EXIT.
+
2012-11-05 Richard Sandiford <rdsandiford@googlemail.com>
PR target/55204
@@ -30,7 +264,7 @@
2012-11-05 Joern Rennecke <joern.rennecke@embecosm.com>
* doc/md.texi (Defining Attributes): Document that we are defining
- HAVE_ATTR_name macors as 1 for defined attributes, and as 0
+ HAVE_ATTR_name macros as 1 for defined attributes, and as 0
for undefined special attributes.
* final.c (asm_insn_count, align_fuzz): Always define.
(insn_current_reference_address): Likewise.
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index 0217b4d9ded..8dbf6812d54 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20121105
+20121106
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 132b6036132..4238a24c49a 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,391 @@
+2012-11-06 Arnaud Charlet <charlet@adacore.com>
+
+ * gcc-interface/Makefile.in (copy-s-oscons): New target.
+
+2012-11-06 Robert Dewar <dewar@adacore.com>
+
+ * err_vars.ads, atree.ads: Minor reformatting.
+
+2012-11-06 Arnaud Charlet <charlet@adacore.com>
+
+ * gcc-interface/Make-lang.in: Update dependencies.
+ * gcc-interface/Makefile.in: Add runtime pairs for Android.
+ Rework handling of s-oscons.ads.
+ * s-osinte-android.ads, s-osinte-android.adb: New files.
+
+2012-11-06 Tristan Gingold <gingold@adacore.com>
+
+ * gcc-interface/trans.c (gnat_to_gnu): For N_Real_Literal, create the
+ binary representation of vax floats.
+
+2012-11-06 Tristan Gingold <gingold@adacore.com>
+
+ * sem_ch9.adb (Analyze_Protected_Type_Declaration): Fix thinko
+ in previous commit.
+
+2012-11-06 Jose Ruiz <ruiz@adacore.com>
+
+ * ali.adb (Scan_ALI): Fix parsing mechanism for -fstack-check.
+
+2012-11-06 Thomas Quinot <quinot@adacore.com>
+
+ * atree.adb, atree.ads, einfo.adb, errout.adb, errout.ads, erroutc.adb,
+ erroutc.ads, errutil.adb, errutil.ads, err_vars.ads, expander.adb,
+ exp_ch13.adb, exp_ch2.adb, exp_ch6.adb, exp_dist.adb, fe.h,
+ fmap.adb, fmap.ads, gprep.adb, makeutl.adb, osint.adb, osint.ads,
+ par_sco.adb, prepcomp.adb, prj-part.adb, prj-proc.adb, scng.adb,
+ sdefault.ads, sem_ch10.adb, sem_ch13.adb, sem_ch2.adb, sem_ch3.adb,
+ sem_ch4.adb, sem_ch5.adb, sem_dim.adb, sem_elab.adb, sem_eval.adb,
+ sem_intr.adb, sem_prag.adb, sem_type.adb, sem_warn.adb, stylesw.adb,
+ stylesw.ads, targparm.adb, targparm.ads (Cascaded_Error): Rename to
+ more descriptive name 'Check_Error_Detected'. Add calls to
+ Check_Error_Detected at places where semantic analysis is abandoned
+ assuming a previously detected error.
+
+2012-11-06 Robert Dewar <dewar@adacore.com>
+
+ * exp_ch4.adb: Minor comment change.
+
+2012-11-06 Robert Dewar <dewar@adacore.com>
+
+ * gnat_ugn.texi: Extensive revision of documentation of overflow
+ checking.
+ * vms_data.ads: Overflow check numbers must be in range 1-3,
+ not 0-3.
+
+2012-11-06 Tristan Gingold <gingold@adacore.com>
+
+ * sem_ch9.adb (Analyze_Protected_Type_Declaration): Emit a
+ warning if pragma Priority is used in presence of an interrupt
+ handler.
+
+2012-11-06 Robert Dewar <dewar@adacore.com>
+
+ * checks.ads, checks.adb, exp_ch4.adb: Minor changes throughout for
+ new overflow checking.
+ * exp_util.adb (Insert_Actions): Remove special casing of
+ Overflow_Check.
+ * gnat1drv.adb (Adjust_Global_Switches): Fixes for new handling
+ of overflow checks.
+ * sem.adb (Analyze): Remove special casing of Overflow_Check
+ (Analyze_List): ditto.
+ * sem_prag.adb (Analyze_Pragma, case Overflow_Checks): Remove
+ SUPPRESSED and change CHECKED to STRICT.
+ * sem_res.adb (Analyze_And_Resolve): No longer treat
+ Overflow_Check specially.
+ (Preanalyze_And_Resolve): ditto.
+ (Resolve): ditto.
+ * snames.ads-tmpl: Replace Name_Checked by Name_Strict.
+ * switch-c.adb (Get_Overflow_Mode): Eliminate 0 setting,
+ CHECKED => STRICT.
+ * types.ads (Overflow_Check_Type): Remove Suppressed, change
+ Checked to Strict (Suppress_Record): Overflow check controlled
+ by Suppress array.
+
+2012-11-06 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_res.adb (Preanalyze_And_Resolve): In Alfa mode do not
+ disable checks, so that flags can be properly set on expressions
+ that are not further expanded.
+
+2012-11-06 Robert Dewar <dewar@adacore.com>
+
+ * exp_attr.adb, sem_attr.adb: Minor reformatting.
+
+2012-11-06 Gary Dismukes <dismukes@adacore.com>
+
+ * exp_attr.adb (Expand_N_Attribute_Reference): Apply a predicate
+ check when evaluating the attribute Valid, and issue a warning
+ about infinite recursion when the check occurs within the
+ predicate function of the prefix's subtype.
+ * exp_ch4.adb (Expand_N_In): Remove test for Is_Discrete_Type
+ when we're checking that there's no predicate check function as a
+ condition for substituting a Valid check for a scalar membership
+ test (substitution should be suppressed for any kind of scalar
+ subtype with a predicate check). Also, don't emit a predicate
+ check when the right operand is a range.
+
+2012-11-06 Robert Dewar <dewar@adacore.com>
+
+ * par_sco.adb, bindgen.adb, exp_vfpt.adb, exp_vfpt.ads, exp_ch2.adb,
+ errout.adb, sem_ch8.adb: Minor reformatting.
+
+2012-11-06 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * einfo.adb: Include Loop_Entry_Attributes to the list of
+ Node/List/Elist10 usage.
+ (Loop_Entry_Attributes): New routine.
+ (Set_Loop_Entry_Attributes): New routine.
+ (Write_Field10_Name): Add an output string for Loop_Entry_Attributes.
+ * einfo.ads: Define new attribute Loop_Entry_Attributes along
+ with its usage in nodes.
+ (Loop_Entry_Attributes): New routine and dedicated pragma Inline.
+ (Set_Loop_Entry_Attributes): New routine and dedicated pragma Inline.
+ * exp_attr.adb (Expand_N_Attribute_Reference): Do not expand
+ Attribute_Loop_Entry here.
+ * exp_ch5.adb: Add with and use clause for Elists;
+ (Expand_Loop_Entry_Attributes): New routine.
+ (Expand_N_Loop_Statement): Add a call to Expand_Loop_Entry_Attributes.
+ * exp_prag.adb (Expand_Pragma_Loop_Assertion): Specialize the
+ search to include multiple nested loops produced by the expansion
+ of Ada 2012 array iterator.
+ * sem_attr.adb: Add with and use clause for Elists.
+ (Analyze_Attribute): Check the legality of attribute Loop_Entry.
+ (Resolve_Attribute): Nothing to do for Loop_Entry.
+ (S14_Attribute): New routine.
+ * snames.ads-tmpl: Add a comment on entries marked with
+ HiLite. Add new name Name_Loop_Entry. Add new attribute
+ Attribute_Loop_Entry.
+
+2012-11-06 Geert Bosch <bosch@adacore.com>
+
+ * eval_fat.adb (Machine, Succ): Fix front end to support static
+ evaluation of attributes on targets with both VAX and IEEE float.
+ * sem_util.ads, sem_util.adb (Has_Denormals, Has_Signed_Zeros):
+ New type-specific functions. Previously we used Denorm_On_Target
+ and Signed_Zeros_On_Target directly, but that doesn't work well
+ for OpenVMS where a single target supports both floating point
+ with and without signed zeros.
+ * sem_attr.adb (Attribute_Denorm, Attribute_Signed_Zeros): Use
+ new Has_Denormals and Has_Signed_Zeros functions to support both
+ IEEE and VAX floating point on a single target.
+
+2012-11-06 Tristan Gingold <gingold@adacore.com>
+
+ * bindgen.adb (System_Interrupts_Used): New variable.
+ (Gen_Adainit): Declare and call
+ Install_Restricted_Handlers_Sequential if System.Interrupts is
+ used when elaboration policy is sequential.
+
+2012-11-06 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_ch8.adb: Complete previous change.
+
+2012-11-06 Tristan Gingold <gingold@adacore.com>
+
+ * fe.h (Get_Vax_Real_Literal_As_Signed): Declare.
+ * eval_fat.adb, eval_fat.ads (Decompose_Int): Move spec in package spec.
+ * exp_vfpt.adb, exp_vfpt.ads (Vax_Real_Literal_As_Signed): New function.
+ (Expand_Vax_Real_Literal): Remove.
+ * exp_ch2.adb (Expand_N_Real_Literal): Do nothing.
+ * sem_eval.adb (Expr_Value_R): Remove special Vax float case,
+ as this is not anymore a special case.
+
+2012-11-06 Yannick Moy <moy@adacore.com>
+
+ * uintp.ads: Minor correction of typo in comment.
+
+2012-11-06 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_prag.adb (Analyze_Pragnma, case Unchecked_Union): remove
+ requirement that discriminants of an unchecked_union must have
+ defaults.
+
+2012-11-06 Vasiliy Fofanov <fofanov@adacore.com>
+
+ * projects.texi: Minor wordsmithing.
+
+2012-11-06 Robert Dewar <dewar@adacore.com>
+
+ * sem_ch9.adb, exp_vfpt.adb, xoscons.adb: Minor reformatting.
+
+2012-11-06 Tristan Gingold <gingold@adacore.com>
+
+ * exp_vfpt.adb: Document VAX float point layout.
+
+2012-11-06 Geert Bosch <bosch@adacore.com>
+
+ * eval_fat.adb (Machine): Don't return -0.0 on targets without
+ signed zeros.
+
+2012-11-06 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_ch9.adb (Analyze_Entry_Call_Alternative,
+ Check_Triggering_Statement): Reject properly an indirect call.
+
+2012-11-06 Pascal Obry <obry@adacore.com>
+
+ * xoscons.adb, xutil.adb, xutil.ads: Add support for post-processing.
+
+2012-11-06 Yannick Moy <moy@adacore.com>
+
+ * s-bignum.adb (Div_Rem): Fix another bug in step D3.
+
+2012-11-06 Tristan Gingold <gingold@adacore.com>
+
+ * s-tarest.adb (Create_Restricted_Task): Call
+ Create_Restricted_Task_Sequential in sequential case.
+
+2012-11-06 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * exp_prag.adb (Expand_Pragma_Loop_Assertion): Do not rewrite the
+ pragma into a null statement as its presence is desirable in -gnatG
+ output.
+
+2012-11-06 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_ch8.adb (Check_Constrained_Object): Do nothing if the
+ renamed object is a limited record.
+
+2012-11-06 Bernard Banner <banner@adacore.com>
+
+ * sysdep.c (_getpagesize): New. Minor reformatting.
+
+2012-11-06 Robert Dewar <dewar@adacore.com>
+
+ * sem_prag.adb: Minor reformatting.
+
+2012-11-06 Robert Dewar <dewar@adacore.com>
+
+ * s-bignum.adb (Div_Rem): Fix bug in step D3.
+ * uintp.adb (UI_Div_Rem): Add comment on bug in step D3.
+
+2012-11-06 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * exp_prag.adb (Expand_Pragma_Loop_Assertion): Update the comment
+ on intended expansion. Reimplement the logic which expands the
+ termination variants.
+ (Process_Increase_Decrease): Update the parameter profile and the
+ comment related to it. Accommodate the new aggregate-like appearance of
+ the termination variants.
+ * sem_prag.adb (Analyze_Pragma): Update the syntax of pragma
+ Loop_Assertion. Reimplement the semantic analysis of the pragma
+ to accommodate the new aggregate-like variant.
+ (Check_Variant): New routine.
+ * snames.ads-tmpl: Change names Name_Decreases and Name_Increases
+ to Name_Decreasing and Name_Increasing respectively. Add name
+ Variant.
+
+2012-11-06 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_eval.adb: Static evaluation of case expressions.
+
+2012-11-06 Robert Dewar <dewar@adacore.com>
+
+ * exp_prag.adb, impunit.adb, exp_ch9.adb, par-ch4.adb,
+ s-tarest.adb: Minor reformatting.
+
+2012-11-06 Tristan Gingold <gingold@adacore.com>
+
+ * s-tposen.ads: Minor comment update.
+
+2012-11-06 Arnaud Charlet <charlet@adacore.com>
+
+ * sysdep.c: Rename sig* wrappers to use unique names.
+
+2012-11-06 Yannick Moy <moy@adacore.com>
+
+ * exp_dbug.adb (Qualify_Entity_Name): Mark entity as having a qualified
+ name after being treated, in formal verification mode.
+
+2012-11-06 Fedor Rybin <frybin@adacore.com>
+
+ * gnat_ugn.texi: Updating gnattest section to reflect changes
+ in default behaviour of the tool.
+
+2012-11-06 Thomas Quinot <quinot@adacore.com>
+
+ * s-oscons-tmplt.c: Interfaces.C now needs to be WITH'd even
+ on platforms that do not support sockets (for the benefit of
+ subtype IOCTL_Req_T).
+
+2012-11-06 Ed Schonberg <schonberg@adacore.com>
+
+ * par-ch4.adb (P_Primary): if-expressions, case-expressions,
+ and quantified expressions are legal if surrounded by parentheses
+ from an enclosing context, such as a call or an instantiation.
+
+2012-11-06 Yannick Moy <moy@adacore.com>
+
+ * impunit.adb (Get_Kind_Of_Unit): Return appropriate kind for
+ predefined implementation files, instead of returning
+ Not_Predefined_Unit on all .adb files.
+
+2012-11-06 Tristan Gingold <gingold@adacore.com>
+
+ * exp_ch9.adb (Build_Activation_Chain_Entity): Return immediately if
+ partition elaboration policy is sequential.
+ (Build_Task_Activation_Call): Likewise. Use
+ Activate_Restricted_Tasks on restricted profile.
+ (Make_Task_Create_Call): Do not use the _Chain
+ parameter if elaboration policy is sequential. Call
+ Create_Restricted_Task_Sequential in that case.
+ * exp_ch3.adb (Build_Initialization_Call): Change condition to
+ support concurrent elaboration policy.
+ (Build_Record_Init_Proc): Likewise.
+ (Init_Formals): Likewise.
+ * bindgen.adb (Gen_Adainit): Declare Partition_Elaboration_Policy
+ and set it in generated code if the elaboration policy is
+ sequential. The procedure called to activate all tasks is now
+ named __gnat_activate_all_tasks.
+ * rtsfind.adb (RE_Activate_Restricted_Task,
+ RE_Create_Restricted_Task_Sequential): New RE_Id literals.
+ * s-tarest.adb (Create_Restricted_Task): Added to create a task without
+ adding it on an activation chain.
+ (Activate_Tasks): Has now a Chain parameter.
+ (Activate_All_Tasks_Sequential): Added. Called by the binder to
+ activate all tasks.
+ (Activate_Restricted_Tasks): Added. Called during elaboration to
+ activate tasks of the units.
+ * s-tarest.ads: Remove pragma Partition_Elaboration_Policy.
+ (Partition_Elaboration_Policy): New variable (set by the binder).
+ (Create_Restricted_Task): Revert removal of the chain parameter.
+ (Create_Restricted_Task_Sequential): New procedure.
+ (Activate_Restricted_Tasks): Revert removal.
+ (Activate_All_Tasks_Sequential): New procedure.
+
+2012-11-06 Bernard Banner <banner@adacore.com>
+
+ * adaint.c Add file macro definitions missing on Android.
+ * adaint.h Avoid definitions related to task affinity and CPU
+ sets since this functionality is missing on the Android
+ * errno.c (__set_errno): Android already contains such a named
+ procedure so do include again.
+ * gsocket.h: Sockets not supported on Android.
+ * init.c: Avoid linux related code not supported on Android.
+ * sysdep.c (sigismember, sigaddset, sigdelset, sigemptyset,
+ sigfillset): wrapper functions since sig routines are defined
+ as inline macros on Android.
+ * terminals.c: Add stubs for terminal related functions not
+ supported on Android.
+
+2012-11-06 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * sem_prag.adb (Analyze_Pragma): Do not
+ output the characters of an illegal argument as it may not have
+ characters to begin with.
+
+2012-11-06 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * exp_prag.adb (Expand_Pragma_Loop_Assertion):
+ Change the order of argument processing to avoid disappearing
+ increase / decrease expressions.
+
+2012-11-06 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * exp_prag.adb: Add with and use clause for Sem_Ch8.
+ (Expand_N_Pragma): Add a new variant to expand pragma Loop_Assertion.
+ (Expand_Pragma_Loop_Assertion): New routine.
+ * par-prag.adb (Prag): The semantic analysis of pragma
+ Loop_Assertion is carried out by Analyze_Pragma. No need for
+ checks in the parser.
+ * sem_prag.adb: Add a reference position value for pragma
+ Loop_Assertion in Sig_Flags.
+ (Analyze_Pragma): Add semantic analysis for pragma Loop_Assertion.
+ * snames.ads-tmpl: Add the following new names:
+ Name_Decreases Name_Increases Name_Loop_Assertion.
+ Add new pragma id Pragma_Loop_Assertion.
+
+2012-11-06 Ed Schonberg <schonberg@adacore.com>
+
+ * exp_ch5.adb: Identifier in iterator must have debug
+ information.
+
+2012-11-06 Arnaud Charlet <charlet@adacore.com>
+
+ * gcc-interface/Makefile.in, gcc-interface/Make-lang.in: Remove
+ duplicate rules handled by Make-generated.in.
+
2012-10-31 Lawrence Crowl <crowl@google.com>
* gcc-interface/utils.c (gnat_write_global_declarations):
diff --git a/gcc/ada/adaint.c b/gcc/ada/adaint.c
index 54244bdf2af..eab3ea5fbae 100644
--- a/gcc/ada/adaint.c
+++ b/gcc/ada/adaint.c
@@ -87,8 +87,8 @@ extern "C" {
#include <unixio.h>
#endif
-#ifdef __vxworks
-/* S_IREAD and S_IWRITE are not defined in VxWorks */
+#if defined (__vxworks) || defined (__ANDROID__)
+/* S_IREAD and S_IWRITE are not defined in VxWorks or Android */
#ifndef S_IREAD
#define S_IREAD (S_IRUSR | S_IRGRP | S_IROTH)
#endif
@@ -3763,7 +3763,16 @@ void __main (void) {}
#endif
#endif
-#if defined (linux)
+#if defined (__ANDROID__)
+
+#include <pthread.h>
+
+void *__gnat_lwp_self (void)
+{
+ return (void *) pthread_self ();
+}
+
+#elif defined (linux)
/* There is no function in the glibc to retrieve the LWP of the current
thread. We need to do a system call in order to retrieve this
information. */
diff --git a/gcc/ada/adaint.h b/gcc/ada/adaint.h
index 6097e61f882..7956e27a709 100644
--- a/gcc/ada/adaint.h
+++ b/gcc/ada/adaint.h
@@ -250,7 +250,11 @@ extern char * __gnat_locate_executable_file (char *, char *);
extern char * __gnat_locate_file_with_predicate (char *, char *,
int (*)(char*));
-#if defined (linux)
+#if defined (__ANDROID__)
+#undef linux
+extern void *__gnat_lwp_self (void);
+
+#elif defined (linux)
extern void *__gnat_lwp_self (void);
/* Routines for interface to required CPU set primitives */
diff --git a/gcc/ada/ali.adb b/gcc/ada/ali.adb
index a85fa4bec2f..0386c05fe5a 100644
--- a/gcc/ada/ali.adb
+++ b/gcc/ada/ali.adb
@@ -970,9 +970,16 @@ package body ALI is
Add_Char_To_Name_Buffer (Getc);
end loop;
- -- If -fstack-check, record that it occurred
-
- if Name_Buffer (1 .. Name_Len) = "-fstack-check" then
+ -- If -fstack-check, record that it occurred. Note that an
+ -- additional string parameter can be specified, in the form of
+ -- -fstack-check={no|generic|specific}. "no" means no checking,
+ -- "generic" means force the use of old-style checking, and
+ -- "specific" means use the best checking method.
+
+ if Name_Len >= 13
+ and then Name_Buffer (1 .. 13) = "-fstack-check"
+ and then Name_Buffer (1 .. Name_Len) /= "-fstack-check=no"
+ then
Stack_Check_Switch_Set := True;
end if;
diff --git a/gcc/ada/atree.adb b/gcc/ada/atree.adb
index dce76e9db41..70dd3801e5c 100644
--- a/gcc/ada/atree.adb
+++ b/gcc/ada/atree.adb
@@ -560,6 +560,20 @@ package body Atree is
(Nodes.Table (E + 2).Field12'Unrestricted_Access)).Convention := Val;
end Basic_Set_Convention;
+ --------------------------
+ -- Check_Error_Detected --
+ --------------------------
+
+ procedure Check_Error_Detected is
+ begin
+ -- An anomaly has been detected which is assumed to be a consequence of
+ -- a previous error. Raise an exception if no error found previously.
+
+ if Total_Errors_Detected = 0 then
+ raise Program_Error;
+ end if;
+ end Check_Error_Detected;
+
-----------------
-- Change_Node --
-----------------
diff --git a/gcc/ada/atree.ads b/gcc/ada/atree.ads
index 305ef9f3978..8c434db6625 100644
--- a/gcc/ada/atree.ads
+++ b/gcc/ada/atree.ads
@@ -276,6 +276,39 @@ package Atree is
Current_Error_Node : Node_Id;
-- Node to place error messages
+ ------------------
+ -- Error Counts --
+ ------------------
+
+ -- The following variables denote the count of errors of various kinds
+ -- detected in the tree. Note that these might be more logically located
+ -- in Err_Vars, but we put it to deal with licensing issues (we need this
+ -- to have the GPL exception licensing, since Check_Error_Detected can
+ -- be called from units with this licensing).
+
+ Serious_Errors_Detected : Nat := 0;
+ -- This is a count of errors that are serious enough to stop expansion,
+ -- and hence to prevent generation of an object file even if the
+ -- switch -gnatQ is set. Initialized to zero at the start of compilation.
+ -- Initialized for -gnatVa use, see comment above.
+
+ Total_Errors_Detected : Nat := 0;
+ -- Number of errors detected so far. Includes count of serious errors and
+ -- non-serious errors, so this value is always greater than or equal to the
+ -- Serious_Errors_Detected value. Initialized to zero at the start of
+ -- compilation. Initialized for -gnatVa use, see comment above.
+
+ Warnings_Detected : Nat := 0;
+ -- Number of warnings detected. Initialized to zero at the start of
+ -- compilation. Initialized for -gnatVa use, see comment above.
+
+ procedure Check_Error_Detected;
+ -- When an anomaly is found in the tree, many semantic routines silently
+ -- bail out, assuming that the anomaly was caused by a previously detected
+ -- error. This routine should be called in these cases, and will raise an
+ -- exception if no error has been detected. This ensure that the anomaly
+ -- is never allowed to go unnoticed.
+
-------------------------------
-- Default Setting of Fields --
-------------------------------
diff --git a/gcc/ada/bindgen.adb b/gcc/ada/bindgen.adb
index e178a57a21b..71741441d09 100644
--- a/gcc/ada/bindgen.adb
+++ b/gcc/ada/bindgen.adb
@@ -82,7 +82,13 @@ package body Bindgen is
-- Flag indicating whether the unit System.Tasking.Restricted.Stages is in
-- the closure of the partition. This is set by Resolve_Binder_Options,
-- and it used to call a routine to active all the tasks at the end of
- -- the elaboration.
+ -- the elaboration when partition elaboration policy is sequential.
+
+ System_Interrupts_Used : Boolean := False;
+ -- Flag indicating whether the unit System.Interrups is in the closure of
+ -- the partition. This is set by Resolve_Binder_Options, and it used to
+ -- attach interrupt handlers at the end of the elaboration when partition
+ -- elaboration policy is sequential.
Lib_Final_Built : Boolean := False;
-- Flag indicating whether the finalize_library rountine has been built
@@ -488,10 +494,26 @@ package body Bindgen is
WBI ("");
end if;
- if System_Tasking_Restricted_Stages_Used then
- WBI (" procedure Activate_Tasks;");
- WBI (" pragma Import (C, Activate_Tasks," &
- " ""__gnat_activate_tasks"");");
+ if System_Interrupts_Used
+ and then Partition_Elaboration_Policy_Specified = 'S'
+ then
+ WBI (" procedure Install_Restricted_Handlers_Sequential;");
+ WBI (" pragma Import (C," &
+ "Install_Restricted_Handlers_Sequential," &
+ " ""__gnat_attach_all_handlers"");");
+ WBI ("");
+ end if;
+
+ if System_Tasking_Restricted_Stages_Used
+ and then Partition_Elaboration_Policy_Specified = 'S'
+ then
+ WBI (" Partition_Elaboration_Policy : Character;");
+ WBI (" pragma Import (C, Partition_Elaboration_Policy," &
+ " ""__gnat_partition_elaboration_policy"");");
+ WBI ("");
+ WBI (" procedure Activate_All_Tasks_Sequential;");
+ WBI (" pragma Import (C, Activate_All_Tasks_Sequential," &
+ " ""__gnat_activate_all_tasks"");");
end if;
WBI (" begin");
@@ -510,8 +532,18 @@ package body Bindgen is
Write_Statement_Buffer;
end if;
+ if System_Tasking_Restricted_Stages_Used
+ and then Partition_Elaboration_Policy_Specified = 'S'
+ then
+ Set_String (" Partition_Elaboration_Policy := '");
+ Set_Char (Partition_Elaboration_Policy_Specified);
+ Set_String ("';");
+ Write_Statement_Buffer;
+ end if;
+
if Main_Priority = No_Main_Priority
and then Main_CPU = No_Main_CPU
+ and then not System_Tasking_Restricted_Stages_Used
then
WBI (" null;");
end if;
@@ -585,12 +617,31 @@ package body Bindgen is
WBI (" pragma Import (C, Handler_Installed, " &
"""__gnat_handler_installed"");");
- -- Import task activation procedure for ravenscar
+ -- Import handlers attach procedure for sequential elaboration policy
- if System_Tasking_Restricted_Stages_Used then
- WBI (" procedure Activate_Tasks;");
- WBI (" pragma Import (C, Activate_Tasks," &
- " ""__gnat_activate_tasks"");");
+ if System_Interrupts_Used
+ and then Partition_Elaboration_Policy_Specified = 'S'
+ then
+ WBI (" procedure Install_Restricted_Handlers_Sequential;");
+ WBI (" pragma Import (C," &
+ "Install_Restricted_Handlers_Sequential," &
+ " ""__gnat_attach_all_handlers"");");
+ WBI ("");
+ end if;
+
+ -- Import task activation procedure for sequential elaboration
+ -- policy.
+
+ if System_Tasking_Restricted_Stages_Used
+ and then Partition_Elaboration_Policy_Specified = 'S'
+ then
+ WBI (" Partition_Elaboration_Policy : Character;");
+ WBI (" pragma Import (C, Partition_Elaboration_Policy," &
+ " ""__gnat_partition_elaboration_policy"");");
+ WBI ("");
+ WBI (" procedure Activate_All_Tasks_Sequential;");
+ WBI (" pragma Import (C, Activate_All_Tasks_Sequential," &
+ " ""__gnat_activate_all_tasks"");");
end if;
-- The import of the soft link which performs library-level object
@@ -727,6 +778,15 @@ package body Bindgen is
Set_String ("';");
Write_Statement_Buffer;
+ if System_Tasking_Restricted_Stages_Used
+ and then Partition_Elaboration_Policy_Specified = 'S'
+ then
+ Set_String (" Partition_Elaboration_Policy := '");
+ Set_Char (Partition_Elaboration_Policy_Specified);
+ Set_String ("';");
+ Write_Statement_Buffer;
+ end if;
+
Gen_Restrictions;
WBI (" Priority_Specific_Dispatching :=");
@@ -913,8 +973,16 @@ package body Bindgen is
WBI (" Freeze_Dispatching_Domains;");
end if;
- if System_Tasking_Restricted_Stages_Used then
- WBI (" Activate_Tasks;");
+ -- Sequential partition elaboration policy
+
+ if Partition_Elaboration_Policy_Specified = 'S' then
+ if System_Interrupts_Used then
+ WBI (" Install_Restricted_Handlers_Sequential;");
+ end if;
+
+ if System_Tasking_Restricted_Stages_Used then
+ WBI (" Activate_All_Tasks_Sequential;");
+ end if;
end if;
-- Case of main program is CIL function or procedure
@@ -2863,6 +2931,10 @@ package body Bindgen is
(System_Tasking_Restricted_Stages_Used,
"system.tasking.restricted.stages%s");
+ -- Ditto for the use of interrupts
+
+ Check_Package (System_Interrupts_Used, "system.interrupts%s");
+
-- Ditto for the use of dispatching domains
Check_Package
diff --git a/gcc/ada/checks.adb b/gcc/ada/checks.adb
index 406d292f09e..b0262dba815 100644
--- a/gcc/ada/checks.adb
+++ b/gcc/ada/checks.adb
@@ -194,18 +194,19 @@ package body Checks is
-- Local Subprograms --
-----------------------
- procedure Apply_Arithmetic_Overflow_Checked_Suppressed (N : Node_Id);
+ procedure Apply_Arithmetic_Overflow_Strict (N : Node_Id);
-- Used to apply arithmetic overflow checks for all cases except operators
-- on signed arithmetic types in MINIMIZED/ELIMINATED case (for which we
- -- call Apply_Arithmetic_Overflow_Minimized_Eliminated below). N is always
- -- a signed integer arithmetic operator (if and case expressions are not
- -- included for this case).
+ -- call Apply_Arithmetic_Overflow_Minimized_Eliminated below). N can be a
+ -- signed integer arithmetic operator (but not an if or case expression).
+ -- It is also called for types other than signed integers.
procedure Apply_Arithmetic_Overflow_Minimized_Eliminated (Op : Node_Id);
-- Used to apply arithmetic overflow checks for the case where the overflow
- -- checking mode is MINIMIZED or ELIMINATED (and the Do_Overflow_Check flag
- -- is known to be set) and we have a signed integer arithmetic op (which
- -- includes the case of if and case expressions).
+ -- checking mode is MINIMIZED or ELIMINATED and we have a signed integer
+ -- arithmetic op (which includes the case of if and case expressions). Note
+ -- that Do_Overflow_Check may or may not be set for node Op. In these modes
+ -- we have work to do even if overflow checking is suppressed.
procedure Apply_Division_Check
(N : Node_Id;
@@ -766,14 +767,12 @@ package body Checks is
begin
-- Use old routine in almost all cases (the only case we are treating
-- specially is the case of a signed integer arithmetic op with the
- -- Do_Overflow_Check flag set on the node, and the overflow checking
- -- mode is MINIMIZED or ELIMINATED).
+ -- overflow checking mode set to MINIMIZED or ELIMINATED).
- if Overflow_Check_Mode (Etype (N)) not in Minimized_Or_Eliminated
- or else not Do_Overflow_Check (N)
+ if Overflow_Check_Mode = Strict
or else not Is_Signed_Integer_Arithmetic_Op (N)
then
- Apply_Arithmetic_Overflow_Checked_Suppressed (N);
+ Apply_Arithmetic_Overflow_Strict (N);
-- Otherwise use the new routine for the case of a signed integer
-- arithmetic op, with Do_Overflow_Check set to True, and the checking
@@ -784,9 +783,9 @@ package body Checks is
end if;
end Apply_Arithmetic_Overflow_Check;
- --------------------------------------------------
- -- Apply_Arithmetic_Overflow_Checked_Suppressed --
- --------------------------------------------------
+ --------------------------------------
+ -- Apply_Arithmetic_Overflow_Strict --
+ --------------------------------------
-- This routine is called only if the type is an integer type, and a
-- software arithmetic overflow check may be needed for op (add, subtract,
@@ -795,21 +794,28 @@ package body Checks is
-- operation into a more complex sequence of tests that ensures that
-- overflow is properly caught.
- -- This is used in SUPPRESSED/CHECKED modes. It is identical to the
- -- code for these cases before the big overflow earthquake, thus ensuring
- -- that in these modes we have compatible behavior (and reliability) to
- -- what was there before. It is also called for types other than signed
- -- integers, and if the Do_Overflow_Check flag is off.
+ -- This is used in CHECKED modes. It is identical to the code for this
+ -- cases before the big overflow earthquake, thus ensuring that in this
+ -- modes we have compatible behavior (and reliability) to what was there
+ -- before. It is also called for types other than signed integers, and if
+ -- the Do_Overflow_Check flag is off.
-- Note: we also call this routine if we decide in the MINIMIZED case
-- to give up and just generate an overflow check without any fuss.
- procedure Apply_Arithmetic_Overflow_Checked_Suppressed (N : Node_Id) is
+ procedure Apply_Arithmetic_Overflow_Strict (N : Node_Id) is
Loc : constant Source_Ptr := Sloc (N);
Typ : constant Entity_Id := Etype (N);
Rtyp : constant Entity_Id := Root_Type (Typ);
begin
+ -- Nothing to do if Do_Overflow_Check not set or overflow checks
+ -- suppressed.
+
+ if not Do_Overflow_Check (N) then
+ return;
+ end if;
+
-- An interesting special case. If the arithmetic operation appears as
-- the operand of a type conversion:
@@ -1067,7 +1073,7 @@ package body Checks is
when RE_Not_Available =>
return;
end;
- end Apply_Arithmetic_Overflow_Checked_Suppressed;
+ end Apply_Arithmetic_Overflow_Strict;
----------------------------------------------------
-- Apply_Arithmetic_Overflow_Minimized_Eliminated --
@@ -1075,7 +1081,6 @@ package body Checks is
procedure Apply_Arithmetic_Overflow_Minimized_Eliminated (Op : Node_Id) is
pragma Assert (Is_Signed_Integer_Arithmetic_Op (Op));
- pragma Assert (Do_Overflow_Check (Op));
Loc : constant Source_Ptr := Sloc (Op);
P : constant Node_Id := Parent (Op);
@@ -1086,8 +1091,7 @@ package body Checks is
Result_Type : constant Entity_Id := Etype (Op);
-- Original result type
- Check_Mode : constant Overflow_Check_Type :=
- Overflow_Check_Mode (Etype (Op));
+ Check_Mode : constant Overflow_Check_Type := Overflow_Check_Mode;
pragma Assert (Check_Mode in Minimized_Or_Eliminated);
Lo, Hi : Uint;
@@ -1102,7 +1106,7 @@ package body Checks is
-- In all these cases, we will process at the higher level (and then
-- this node will be processed during the downwards recursion that
- -- is part of the processing in Minimize_Eliminate_Overflow_Checks).
+ -- is part of the processing in Minimize_Eliminate_Overflows).
if Is_Signed_Integer_Arithmetic_Op (P)
or else Nkind (P) in N_Membership_Test
@@ -1127,7 +1131,7 @@ package body Checks is
-- will still be in Bignum mode if either of its operands are of type
-- Bignum).
- Minimize_Eliminate_Overflow_Checks (Op, Lo, Hi, Top_Level => True);
+ Minimize_Eliminate_Overflows (Op, Lo, Hi, Top_Level => True);
-- That call may but does not necessarily change the result type of Op.
-- It is the job of this routine to undo such changes, so that at the
@@ -1213,7 +1217,7 @@ package body Checks is
-- Here we know the result is Long_Long_Integer'Base, of that it has
-- been rewritten because the parent operation is a conversion. See
- -- Apply_Arithmetic_Overflow_Checked_Suppressed.Conversion_Optimization.
+ -- Apply_Arithmetic_Overflow_Strict.Conversion_Optimization.
else
pragma Assert
@@ -1678,7 +1682,7 @@ package body Checks is
Left : constant Node_Id := Left_Opnd (N);
Right : constant Node_Id := Right_Opnd (N);
- Mode : constant Overflow_Check_Type := Overflow_Check_Mode (Typ);
+ Mode : constant Overflow_Check_Type := Overflow_Check_Mode;
-- Current overflow checking mode
LLB : Uint;
@@ -1693,15 +1697,13 @@ package body Checks is
-- Don't actually use this value
begin
- -- If we are operating in MINIMIZED or ELIMINATED mode, and the
- -- Do_Overflow_Check flag is set and we are operating on signed
- -- integer types, then the only thing this routine does is to call
- -- Apply_Arithmetic_Overflow_Minimized_Eliminated. That procedure will
- -- (possibly later on during recursive downward calls), make sure that
- -- any needed overflow and division checks are properly applied.
+ -- If we are operating in MINIMIZED or ELIMINATED mode, and we are
+ -- operating on signed integer types, then the only thing this routine
+ -- does is to call Apply_Arithmetic_Overflow_Minimized_Eliminated. That
+ -- procedure will (possibly later on during recursive downward calls),
+ -- ensure that any needed overflow/division checks are properly applied.
if Mode in Minimized_Or_Eliminated
- and then Do_Overflow_Check (N)
and then Is_Signed_Integer_Type (Typ)
then
Apply_Arithmetic_Overflow_Minimized_Eliminated (N);
@@ -1726,7 +1728,9 @@ package body Checks is
-- Deal with overflow check
- if Do_Overflow_Check (N) and then Mode /= Suppressed then
+ if Do_Overflow_Check (N)
+ and then not Overflow_Checks_Suppressed (Etype (N))
+ then
-- Test for extremely annoying case of xxx'First divided by -1
-- for division of signed integer types (only overflow case).
@@ -3093,6 +3097,7 @@ package body Checks is
begin
if not Overflow_Checks_Suppressed (Target_Base)
+ and then not Overflow_Checks_Suppressed (Target_Type)
and then not
In_Subrange_Of (Expr_Type, Target_Base, Fixed_Int => Conv_OK)
and then not Float_To_Int
@@ -4420,7 +4425,7 @@ package body Checks is
procedure Enable_Overflow_Check (N : Node_Id) is
Typ : constant Entity_Id := Base_Type (Etype (N));
- Mode : constant Overflow_Check_Type := Overflow_Check_Mode (Etype (N));
+ Mode : constant Overflow_Check_Type := Overflow_Check_Mode;
Chk : Nat;
OK : Boolean;
Ent : Entity_Id;
@@ -4438,7 +4443,7 @@ package body Checks is
-- No check if overflow checks suppressed for type of node
- if Mode = Suppressed then
+ if Overflow_Checks_Suppressed (Etype (N)) then
return;
-- Nothing to do for unsigned integer types, which do not overflow
@@ -4447,23 +4452,28 @@ package body Checks is
return;
end if;
- -- This is the point at which processing for CHECKED mode diverges
+ -- This is the point at which processing for STRICT mode diverges
-- from processing for MINIMIZED/ELIMINATED modes. This divergence is
-- probably more extreme that it needs to be, but what is going on here
-- is that when we introduced MINIMIZED/ELIMINATED modes, we wanted
- -- to leave the processing for CHECKED mode untouched. There were
+ -- to leave the processing for STRICT mode untouched. There were
-- two reasons for this. First it avoided any incompatible change of
- -- behavior. Second, it guaranteed that CHECKED mode continued to be
+ -- behavior. Second, it guaranteed that STRICT mode continued to be
-- legacy reliable.
- -- The big difference is that in CHECKED mode there is a fair amount of
+ -- The big difference is that in STRICT mode there is a fair amount of
-- circuitry to try to avoid setting the Do_Overflow_Check flag if we
-- know that no check is needed. We skip all that in the two new modes,
-- since really overflow checking happens over a whole subtree, and we
-- do the corresponding optimizations later on when applying the checks.
if Mode in Minimized_Or_Eliminated then
- Activate_Overflow_Check (N);
+ if not (Overflow_Checks_Suppressed (Etype (N)))
+ and then not (Is_Entity_Name (N)
+ and then Overflow_Checks_Suppressed (Entity (N)))
+ then
+ Activate_Overflow_Check (N);
+ end if;
if Debug_Flag_CC then
w ("Minimized/Eliminated mode");
@@ -4472,7 +4482,7 @@ package body Checks is
return;
end if;
- -- Remainder of processing is for Checked case, and is unchanged from
+ -- Remainder of processing is for STRICT case, and is unchanged from
-- earlier versions preceding the addition of MINIMIZED/ELIMINATED.
-- Nothing to do if the range of the result is known OK. We skip this
@@ -6685,9 +6695,9 @@ package body Checks is
New_Reference_To (M, Loc))))));
end Make_Bignum_Block;
- ----------------------------------------
- -- Minimize_Eliminate_Overflow_Checks --
- ----------------------------------------
+ ----------------------------------
+ -- Minimize_Eliminate_Overflows --
+ ----------------------------------
-- This is a recursive routine that is called at the top of an expression
-- tree to properly process overflow checking for a whole subtree by making
@@ -6697,14 +6707,13 @@ package body Checks is
-- it would interfere with semantic analysis).
-- What happens is that if MINIMIZED/ELIMINATED mode is in effect then
- -- the operator expansion routines, as well as the expansion routines
- -- for if/case expression test the Do_Overflow_Check flag and if it is
- -- set they (for the moment) do nothing except call the routine to apply
- -- the overflow check (Apply_Arithmetic_Overflow_Check). That routine
- -- does nothing for non top-level nodes, so at the point where the call
- -- is made for the top level node, the entire expression subtree has not
- -- been expanded, or processed for overflow. All that has to happen as a
- -- result of the top level call to this routine.
+ -- the operator expansion routines, as well as the expansion routines for
+ -- if/case expression, do nothing (for the moment) except call the routine
+ -- to apply the overflow check (Apply_Arithmetic_Overflow_Check). That
+ -- routine does nothing for non top-level nodes, so at the point where the
+ -- call is made for the top level node, the entire expression subtree has
+ -- not been expanded, or processed for overflow. All that has to happen as
+ -- a result of the top level call to this routine.
-- As noted above, the overflow processing works by making recursive calls
-- for the operands, and figuring out what to do, based on the processing
@@ -6716,11 +6725,10 @@ package body Checks is
-- the node (if it has been modified by the overflow check processing). The
-- Analyzed_Flag is set to False before the reexpand/reanalyze. To avoid
-- a recursive call into the whole overflow apparatus, an important rule
- -- for this call is that either Do_Overflow_Check must be False, or if
- -- it is set, then the overflow checking mode must be temporarily set
- -- to CHECKED/SUPPRESSED. Either step will avoid the unwanted recursion.
+ -- for this call is that the overflow handling mode must be temporarily set
+ -- to STRICT.
- procedure Minimize_Eliminate_Overflow_Checks
+ procedure Minimize_Eliminate_Overflows
(N : Node_Id;
Lo : out Uint;
Hi : out Uint;
@@ -6730,7 +6738,7 @@ package body Checks is
pragma Assert (Is_Signed_Integer_Type (Rtyp));
-- Result type, must be a signed integer type
- Check_Mode : constant Overflow_Check_Type := Overflow_Check_Mode (Empty);
+ Check_Mode : constant Overflow_Check_Type := Overflow_Check_Mode;
pragma Assert (Check_Mode in Minimized_Or_Eliminated);
Loc : constant Source_Ptr := Sloc (N);
@@ -6764,18 +6772,24 @@ package body Checks is
-- Set True if one or more operands is already of type Long_Long_Integer
-- which means that if the result is known to be in the result type
-- range, then we must convert such operands back to the result type.
- -- This switch is properly set only when Bignum_Operands is False.
-
- procedure Reexpand (C : Suppressed_Or_Checked);
- -- This is called when we have not modified the node, so we do not need
- -- to reanalyze it. But we do want to reexpand it in either SUPPRESSED
- -- or CHECKED mode (as indicated by the argument C) to get proper
- -- expansion. It is important that we reset the mode to SUPPRESSED or
- -- CHECKED, since if we leave it in MINIMIZED or ELIMINATED mode we
- -- would reenter this routine recursively which would not be good!
- -- Note that this is not just an optimization, testing has showed up
- -- several complex cases in which reanalyzing an already analyzed node
- -- causes incorrect behavior.
+
+ procedure Reanalyze (Typ : Entity_Id; Suppress : Boolean := False);
+ -- This is called when we have modified the node and we therefore need
+ -- to reanalyze it. It is important that we reset the mode to STRICT for
+ -- this reanalysis, since if we leave it in MINIMIZED or ELIMINATED mode
+ -- we would reenter this routine recursively which would not be good!
+ -- The argument Suppress is set True if we also want to suppress
+ -- overflow checking for the reexpansion (this is set when we know
+ -- overflow is not possible). Typ is the type for the reanalysis.
+
+ procedure Reexpand (Suppress : Boolean := False);
+ -- This is like Reanalyze, but does not do the Analyze step, it only
+ -- does a reexpansion. We do this reexpansion in STRICT mode, so that
+ -- instead of reentering the MINIMIZED/ELIMINATED mode processing, we
+ -- follow the normal expansion path (e.g. converting A**4 to A**2**2).
+ -- Note that skipping reanalysis is not just an optimization, testing
+ -- has showed up several complex cases in which reanalyzing an already
+ -- analyzed node causes incorrect behavior.
function In_Result_Range return Boolean;
-- Returns True iff Lo .. Hi are within range of the result type
@@ -6829,25 +6843,62 @@ package body Checks is
end if;
end Min;
+ ---------------
+ -- Reanalyze --
+ ---------------
+
+ procedure Reanalyze (Typ : Entity_Id; Suppress : Boolean := False) is
+ Svg : constant Overflow_Check_Type :=
+ Scope_Suppress.Overflow_Checks_General;
+ Sva : constant Overflow_Check_Type :=
+ Scope_Suppress.Overflow_Checks_Assertions;
+ Svo : constant Boolean :=
+ Scope_Suppress.Suppress (Overflow_Check);
+
+ begin
+ Scope_Suppress.Overflow_Checks_General := Strict;
+ Scope_Suppress.Overflow_Checks_Assertions := Strict;
+
+ if Suppress then
+ Scope_Suppress.Suppress (Overflow_Check) := True;
+ end if;
+
+ Analyze_And_Resolve (N, Typ);
+
+ Scope_Suppress.Suppress (Overflow_Check) := Svo;
+ Scope_Suppress.Overflow_Checks_General := Svg;
+ Scope_Suppress.Overflow_Checks_Assertions := Sva;
+ end Reanalyze;
+
--------------
-- Reexpand --
--------------
- procedure Reexpand (C : Suppressed_Or_Checked) is
+ procedure Reexpand (Suppress : Boolean := False) is
Svg : constant Overflow_Check_Type :=
Scope_Suppress.Overflow_Checks_General;
Sva : constant Overflow_Check_Type :=
Scope_Suppress.Overflow_Checks_Assertions;
+ Svo : constant Boolean :=
+ Scope_Suppress.Suppress (Overflow_Check);
+
begin
- Scope_Suppress.Overflow_Checks_General := C;
- Scope_Suppress.Overflow_Checks_Assertions := C;
+ Scope_Suppress.Overflow_Checks_General := Strict;
+ Scope_Suppress.Overflow_Checks_Assertions := Strict;
Set_Analyzed (N, False);
+
+ if Suppress then
+ Scope_Suppress.Suppress (Overflow_Check) := True;
+ end if;
+
Expand (N);
+
+ Scope_Suppress.Suppress (Overflow_Check) := Svo;
Scope_Suppress.Overflow_Checks_General := Svg;
Scope_Suppress.Overflow_Checks_Assertions := Sva;
end Reexpand;
- -- Start of processing for Minimize_Eliminate_Overflow_Checks
+ -- Start of processing for Minimize_Eliminate_Overflows
begin
-- Case where we do not have a signed integer arithmetic operation
@@ -6884,14 +6935,14 @@ package body Checks is
begin
Bignum_Operands := False;
- Minimize_Eliminate_Overflow_Checks
+ Minimize_Eliminate_Overflows
(Then_DE, Lo, Hi, Top_Level => False);
if Lo = No_Uint then
Bignum_Operands := True;
end if;
- Minimize_Eliminate_Overflow_Checks
+ Minimize_Eliminate_Overflows
(Else_DE, Rlo, Rhi, Top_Level => False);
if Rlo = No_Uint then
@@ -6918,8 +6969,7 @@ package body Checks is
Convert_To_Bignum (Else_DE)),
Is_Elsif => Is_Elsif (N)));
- Analyze_And_Resolve
- (N, RTE (RE_Bignum), Suppress => Overflow_Check);
+ Reanalyze (RTE (RE_Bignum), Suppress => True);
-- If we have no Long_Long_Integer operands, then we are in result
-- range, since it means that none of our operands felt the need
@@ -6930,7 +6980,7 @@ package body Checks is
elsif not Long_Long_Integer_Operands then
Set_Do_Overflow_Check (N, False);
- Reexpand (Suppressed);
+ Reexpand;
-- Otherwise convert us to long long integer mode. Note that we
-- don't need any further overflow checking at this level.
@@ -6943,8 +6993,7 @@ package body Checks is
-- Now reanalyze with overflow checks off
Set_Do_Overflow_Check (N, False);
- Set_Analyzed (N, False);
- Analyze_And_Resolve (N, LLIB, Suppress => Overflow_Check);
+ Reanalyze (LLIB, Suppress => True);
end if;
end;
@@ -6968,7 +7017,7 @@ package body Checks is
Aexp : constant Node_Id := Expression (Alt);
begin
- Minimize_Eliminate_Overflow_Checks
+ Minimize_Eliminate_Overflows
(Aexp, Lo, Hi, Top_Level => False);
if Lo = No_Uint then
@@ -6991,7 +7040,7 @@ package body Checks is
if not (Bignum_Operands or Long_Long_Integer_Operands) then
Set_Do_Overflow_Check (N, False);
- Reexpand (Suppressed);
+ Reexpand (Suppress => True);
-- Otherwise we are going to rebuild the case expression using
-- either bignum or long long integer operands throughout.
@@ -7028,7 +7077,7 @@ package body Checks is
Expression => Expression (N),
Alternatives => New_Alts));
- Analyze_And_Resolve (N, Rtype, Suppress => Overflow_Check);
+ Reanalyze (Rtype, Suppress => True);
end;
end if;
end;
@@ -7040,11 +7089,11 @@ package body Checks is
-- operands to get the ranges (and to properly process the subtree
-- that lies below us!)
- Minimize_Eliminate_Overflow_Checks
+ Minimize_Eliminate_Overflows
(Right_Opnd (N), Rlo, Rhi, Top_Level => False);
if Binary then
- Minimize_Eliminate_Overflow_Checks
+ Minimize_Eliminate_Overflows
(Left_Opnd (N), Llo, Lhi, Top_Level => False);
end if;
@@ -7356,7 +7405,7 @@ package body Checks is
and then In_Result_Range
then
Set_Do_Overflow_Check (N, False);
- Reexpand (Suppressed);
+ Reexpand (Suppress => True);
return;
-- Here we know that we are not in the result range, and in the general
@@ -7380,22 +7429,17 @@ package body Checks is
and then Nkind (Parent (N)) /= N_Type_Conversion
then
- -- Here we will keep the original types, but we do need an overflow
- -- check, so we will set Do_Overflow_Check to True (actually it is
- -- true already, or how would we have got here?).
-
- pragma Assert (Do_Overflow_Check (N));
- Set_Analyzed (N, False);
+ -- Here keep original types, but we need to complete analysis
-- One subtlety. We can't just go ahead and do an analyze operation
-- here because it will cause recursion into the whole MINIMIZED/
-- ELIMINATED overflow processing which is not what we want. Here
-- we are at the top level, and we need a check against the result
- -- mode (i.e. we want to use Checked mode). So do exactly that!
+ -- mode (i.e. we want to use STRICT mode). So do exactly that!
-- Also, we have not modified the node, so this is a case where
-- we need to reexpand, but not reanalyze.
- Reexpand (Checked);
+ Reexpand;
return;
-- Cases where we do the operation in Bignum mode. This happens either
@@ -7421,17 +7465,18 @@ package body Checks is
-- set True). In this case, there is no point in moving into Bignum
-- mode to prevent overflow if the caller will immediately convert
-- the Bignum value back to LLI with an overflow check. It's more
- -- efficient to stay in LLI mode with an overflow check.
+ -- efficient to stay in LLI mode with an overflow check (if needed)
if Check_Mode = Minimized
or else (Top_Level and not Bignum_Operands)
then
- Enable_Overflow_Check (N);
+ if Do_Overflow_Check (N) then
+ Enable_Overflow_Check (N);
+ end if;
- -- Since we are doing an overflow check, the result has to be in
- -- Long_Long_Integer mode, so adjust the possible range to reflect
- -- this. Note these calls also change No_Uint values from the top
- -- level case to LLI bounds.
+ -- The result now has to be in Long_Long_Integer mode, so adjust
+ -- the possible range to reflect this. Note these calls also
+ -- change No_Uint values from the top level case to LLI bounds.
Max (Lo, LLLo);
Min (Hi, LLHi);
@@ -7500,7 +7545,7 @@ package body Checks is
Make_Function_Call (Loc,
Name => New_Occurrence_Of (Fent, Loc),
Parameter_Associations => Args));
- Analyze_And_Resolve (N, RTE (RE_Bignum));
+ Reanalyze (RTE (RE_Bignum), Suppress => True);
-- Indicate result is Bignum mode
@@ -7557,48 +7602,36 @@ package body Checks is
-- we will complete any division checks (since we have not changed the
-- setting of the Do_Division_Check flag).
- -- If no overflow check, suppress overflow check to avoid an infinite
- -- recursion into this procedure.
+ -- We do this reanalysis in STRICT mode to avoid recursion into the
+ -- MINIMIZED/ELIMINATED handling, since we are now done with that!
- if not Do_Overflow_Check (N) then
- Analyze_And_Resolve (N, LLIB, Suppress => Overflow_Check);
+ declare
+ SG : constant Overflow_Check_Type :=
+ Scope_Suppress.Overflow_Checks_General;
+ SA : constant Overflow_Check_Type :=
+ Scope_Suppress.Overflow_Checks_Assertions;
- -- If an overflow check is required, do it in normal CHECKED mode.
- -- That avoids an infinite recursion, making sure we get a normal
- -- overflow check.
+ begin
+ Scope_Suppress.Overflow_Checks_General := Strict;
+ Scope_Suppress.Overflow_Checks_Assertions := Strict;
- else
- declare
- SG : constant Overflow_Check_Type :=
- Scope_Suppress.Overflow_Checks_General;
- SA : constant Overflow_Check_Type :=
- Scope_Suppress.Overflow_Checks_Assertions;
- begin
- Scope_Suppress.Overflow_Checks_General := Checked;
- Scope_Suppress.Overflow_Checks_Assertions := Checked;
- Analyze_And_Resolve (N, LLIB);
- Scope_Suppress.Overflow_Checks_General := SG;
- Scope_Suppress.Overflow_Checks_Assertions := SA;
- end;
- end if;
- end Minimize_Eliminate_Overflow_Checks;
+ if not Do_Overflow_Check (N) then
+ Reanalyze (LLIB, Suppress => True);
+ else
+ Reanalyze (LLIB);
+ end if;
+
+ Scope_Suppress.Overflow_Checks_General := SG;
+ Scope_Suppress.Overflow_Checks_Assertions := SA;
+ end;
+ end Minimize_Eliminate_Overflows;
-------------------------
-- Overflow_Check_Mode --
-------------------------
- function Overflow_Check_Mode (E : Entity_Id) return Overflow_Check_Type is
+ function Overflow_Check_Mode return Overflow_Check_Type is
begin
- -- Check overflow suppressed on entity
-
- if Present (E) and then Checks_May_Be_Suppressed (E) then
- if Is_Check_Suppressed (E, Overflow_Check) then
- return Suppressed;
- end if;
- end if;
-
- -- Else return appropriate scope setting
-
if In_Assertion_Expr = 0 then
return Scope_Suppress.Overflow_Checks_General;
else
@@ -7612,7 +7645,11 @@ package body Checks is
function Overflow_Checks_Suppressed (E : Entity_Id) return Boolean is
begin
- return Overflow_Check_Mode (E) = Suppressed;
+ if Present (E) and then Checks_May_Be_Suppressed (E) then
+ return Is_Check_Suppressed (E, Overflow_Check);
+ else
+ return Scope_Suppress.Suppress (Overflow_Check);
+ end if;
end Overflow_Checks_Suppressed;
-----------------------------
diff --git a/gcc/ada/checks.ads b/gcc/ada/checks.ads
index f7a4399386d..f2919e2ad60 100644
--- a/gcc/ada/checks.ads
+++ b/gcc/ada/checks.ads
@@ -72,12 +72,11 @@ package Checks is
-- determine whether check C is suppressed either on the entity E or
-- as the result of a scope suppress pragma. If Checks_May_Be_Suppressed
-- is False, then the status of the check can be determined simply by
- -- examining Scope_Checks (C), so this routine is not called in that case.
+ -- examining Scope_Suppress, so this routine is not called in that case.
- function Overflow_Check_Mode (E : Entity_Id) return Overflow_Check_Type;
+ function Overflow_Check_Mode return Overflow_Check_Type;
-- Returns current overflow checking mode, taking into account whether
- -- we are inside an assertion expression. Always returns Suppressed if
- -- overflow checks are suppressed for entity E.
+ -- we are inside an assertion expression.
-------------------------------------------
-- Procedures to Activate Checking Flags --
@@ -142,7 +141,10 @@ package Checks is
-- overflow checking for dependent expressions. This routine handles
-- front end vs back end overflow checks (in the front end case it expands
-- the necessary check). Note that divide is handled separately using
- -- Apply_Divide_Checks.
+ -- Apply_Divide_Checks. Node N may or may not have Do_Overflow_Check.
+ -- In STRICT mode, there is nothing to do if this flag is off, but in
+ -- MINIMIZED/ELIMINATED mode we still have to deal with possible use
+ -- of doing operations in Long_Long_Integer or Bignum mode.
procedure Apply_Constraint_Check
(N : Node_Id;
@@ -266,15 +268,16 @@ package Checks is
-- Insert_Action of the whole block (it is returned unanalyzed). The Loc
-- parameter is used to supply Sloc values for the constructed tree.
- procedure Minimize_Eliminate_Overflow_Checks
+ procedure Minimize_Eliminate_Overflows
(N : Node_Id;
Lo : out Uint;
Hi : out Uint;
Top_Level : Boolean);
-- This is the main routine for handling MINIMIZED and ELIMINATED overflow
- -- checks. On entry N is a node whose result is a signed integer subtype.
- -- If the node is an arithmetic operation, then a range analysis is carried
- -- out, and there are three possibilities:
+ -- processing. On entry N is a node whose result is a signed integer
+ -- subtype. The Do_Overflow_Check flag may or may not be set on N. If the
+ -- node is an arithmetic operation, then a range analysis is carried out,
+ -- and there are three possibilities:
--
-- The node is left unchanged (apart from expansion of an exponentiation
-- operation). This happens if the routine can determine that the result
@@ -313,16 +316,16 @@ package Checks is
-- The routine is called in three situations if we are operating in either
-- MINIMIZED or ELIMINATED modes.
--
- -- Overflow checks applied to the top node of an expression tree when
+ -- Overflow processing applied to the top node of an expression tree when
-- that node is an arithmetic operator. In this case the result is
-- converted to the appropriate result type (there is special processing
-- when the parent is a conversion, see body for details).
--
- -- Overflow checks are applied to the operands of a comparison operation.
+ -- Overflow processing applied to the operands of a comparison operation.
-- In this case, the comparison is done on the result Long_Long_Integer
-- or Bignum values, without raising any exceptions.
--
- -- Overflow checks are applied to the left operand of a membership test.
+ -- Overflow processing applied to the left operand of a membership test.
-- In this case no exception is raised if a Long_Long_Integer or Bignum
-- result is outside the range of the type of that left operand (it is
-- just that the result of IN is false in that case).
@@ -332,13 +335,13 @@ package Checks is
--
-- Top_Level is used to avoid inefficient unnecessary transitions into the
-- Bignum domain. If Top_Level is True, it means that the caller will have
- -- to convert any Bignum value back to Long_Long_Integer, checking that the
- -- value is in range. This is the normal case for a top level operator in
- -- a subexpression. There is no point in going into Bignum mode to avoid an
- -- overflow just so we can check for overflow the next moment. For calls
- -- from comparisons and membership tests, and for all recursive calls, we
- -- do want to transition into the Bignum domain if necessary. Note that
- -- this setting is only relevant in ELIMINATED mode.
+ -- to convert any Bignum value back to Long_Long_Integer, possibly checking
+ -- that the value is in range. This is the normal case for a top level
+ -- operator in a subexpression. There is no point in going into Bignum mode
+ -- to avoid an overflow just so we can check for overflow the next moment.
+ -- For calls from comparisons and membership tests, and for all recursive
+ -- calls, we do want to transition into the Bignum domain if necessary.
+ -- Note that this setting is only relevant in ELIMINATED mode.
-------------------------------------------------------
-- Control and Optimization of Range/Overflow Checks --
@@ -370,9 +373,7 @@ package Checks is
-- has no effect. If a check is needed then this routine sets the flag
-- Do_Overflow_Check in node N to True, unless it can be determined that
-- the check is not needed. The only condition under which this is the
- -- case is if there was an identical check earlier on. These optimziations
- -- apply to CHECKED mode, but not to MINIMIZED/ELIMINATED modes. See the
- -- body for a full explanation.
+ -- case is if there was an identical check earlier on.
procedure Enable_Range_Check (N : Node_Id);
-- Set Do_Range_Check flag in node N True, unless it can be determined
diff --git a/gcc/ada/einfo.adb b/gcc/ada/einfo.adb
index bfa7593dc5d..212849791fb 100644
--- a/gcc/ada/einfo.adb
+++ b/gcc/ada/einfo.adb
@@ -90,6 +90,7 @@ package body Einfo is
-- Discriminal_Link Node10
-- Float_Rep Uint10 (but returns Float_Rep_Kind)
-- Handler_Records List10
+ -- Loop_Entry_Attributes Elist10
-- Normalized_Position_Max Uint10
-- Component_Bit_Offset Uint11
@@ -2246,6 +2247,12 @@ package body Einfo is
return Node16 (Id);
end Lit_Strings;
+ function Loop_Entry_Attributes (Id : E) return L is
+ begin
+ pragma Assert (Ekind (Id) = E_Loop);
+ return Elist10 (Id);
+ end Loop_Entry_Attributes;
+
function Low_Bound_Tested (Id : E) return B is
begin
return Flag205 (Id);
@@ -4791,6 +4798,12 @@ package body Einfo is
Set_Node16 (Id, V);
end Set_Lit_Strings;
+ procedure Set_Loop_Entry_Attributes (Id : E; V : L) is
+ begin
+ pragma Assert (Ekind (Id) = E_Loop);
+ Set_Elist10 (Id, V);
+ end Set_Loop_Entry_Attributes;
+
procedure Set_Low_Bound_Tested (Id : E; V : B := True) is
begin
pragma Assert (Is_Formal (Id));
@@ -6967,6 +6980,7 @@ package body Einfo is
-- previous errors.
elsif No (Etyp) then
+ Check_Error_Detected;
return T;
elsif Is_Private_Type (T) and then Etyp = Full_View (T) then
@@ -7874,6 +7888,9 @@ package body Einfo is
E_Procedure =>
Write_Str ("Handler_Records");
+ when E_Loop =>
+ Write_Str ("Loop_Entry_Attributes");
+
when E_Component |
E_Discriminant =>
Write_Str ("Normalized_Position_Max");
diff --git a/gcc/ada/einfo.ads b/gcc/ada/einfo.ads
index 08fba5a80c9..e4af8cf23fb 100644
--- a/gcc/ada/einfo.ads
+++ b/gcc/ada/einfo.ads
@@ -2959,6 +2959,10 @@ package Einfo is
-- the nature and use of this entity for implementing the Image and
-- Value attributes for the enumeration type in question.
+-- Loop_Entry_Attributes (Elist10)
+-- Defined for loop statement scopes. The list contains all Loop_Entry
+-- attribute references related to the target loop.
+
-- Low_Bound_Tested (Flag205)
-- Defined in all entities. Currently this can only be set True for
-- formal parameter entries of a standard unconstrained one-dimensional
@@ -5389,6 +5393,7 @@ package Einfo is
-- E_Loop
-- First_Exit_Statement (Node8)
+ -- Loop_Entry_Attributes (Elist10)
-- Has_Exit (Flag47)
-- Has_Master_Entity (Flag21)
-- Has_Nested_Block_With_Handler (Flag101)
@@ -6309,6 +6314,7 @@ package Einfo is
function Limited_View (Id : E) return E;
function Lit_Indexes (Id : E) return E;
function Lit_Strings (Id : E) return E;
+ function Loop_Entry_Attributes (Id : E) return L;
function Low_Bound_Tested (Id : E) return B;
function Machine_Radix_10 (Id : E) return B;
function Master_Id (Id : E) return E;
@@ -6905,6 +6911,7 @@ package Einfo is
procedure Set_Limited_View (Id : E; V : E);
procedure Set_Lit_Indexes (Id : E; V : E);
procedure Set_Lit_Strings (Id : E; V : E);
+ procedure Set_Loop_Entry_Attributes (Id : E; V : L);
procedure Set_Low_Bound_Tested (Id : E; V : B := True);
procedure Set_Machine_Radix_10 (Id : E; V : B := True);
procedure Set_Master_Id (Id : E; V : E);
@@ -7623,6 +7630,7 @@ package Einfo is
pragma Inline (Limited_View);
pragma Inline (Lit_Indexes);
pragma Inline (Lit_Strings);
+ pragma Inline (Loop_Entry_Attributes);
pragma Inline (Low_Bound_Tested);
pragma Inline (Machine_Radix_10);
pragma Inline (Master_Id);
@@ -8028,6 +8036,7 @@ package Einfo is
pragma Inline (Set_Limited_View);
pragma Inline (Set_Lit_Indexes);
pragma Inline (Set_Lit_Strings);
+ pragma Inline (Set_Loop_Entry_Attributes);
pragma Inline (Set_Low_Bound_Tested);
pragma Inline (Set_Machine_Radix_10);
pragma Inline (Set_Master_Id);
diff --git a/gcc/ada/err_vars.ads b/gcc/ada/err_vars.ads
index e17e1fe9573..6afa4e3d765 100644
--- a/gcc/ada/err_vars.ads
+++ b/gcc/ada/err_vars.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 1992-2011, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -38,25 +38,11 @@ package Err_Vars is
-- been initialized, so we initialize some variables to avoid exceptions
-- from invalid values in such cases.
- ------------------
- -- Error Counts --
- ------------------
-
- Serious_Errors_Detected : Nat := 0;
- -- This is a count of errors that are serious enough to stop expansion,
- -- and hence to prevent generation of an object file even if the
- -- switch -gnatQ is set. Initialized to zero at the start of compilation.
- -- Initialized for -gnatVa use, see comment above.
-
- Total_Errors_Detected : Nat := 0;
- -- Number of errors detected so far. Includes count of serious errors and
- -- non-serious errors, so this value is always greater than or equal to the
- -- Serious_Errors_Detected value. Initialized to zero at the start of
- -- compilation. Initialized for -gnatVa use, see comment above.
-
- Warnings_Detected : Nat := 0;
- -- Number of warnings detected. Initialized to zero at the start of
- -- compilation. Initialized for -gnatVa use, see comment above.
+ -- Note on error counts (Serious_Errors_Detected, Total_Errors_Detected,
+ -- Warnings_Detected). These counts might more logically appear in this
+ -- unit, but we place them in atree.adb, because of licensing issues. We
+ -- need to be able to access these counts from units that have the more
+ -- general licensing conditions.
----------------------------------
-- Error Message Mode Variables --
diff --git a/gcc/ada/errno.c b/gcc/ada/errno.c
index 93c8660490a..2fbeacc3ec1 100644
--- a/gcc/ada/errno.c
+++ b/gcc/ada/errno.c
@@ -58,8 +58,10 @@ __get_errno(void)
return errno;
}
+#ifndef __ANDROID__
void
__set_errno(int err)
{
errno = err;
}
+#endif
diff --git a/gcc/ada/errout.adb b/gcc/ada/errout.adb
index 64062b29e9c..6f450200ef9 100644
--- a/gcc/ada/errout.adb
+++ b/gcc/ada/errout.adb
@@ -198,21 +198,6 @@ package body Errout is
-- spec for precise definition of the conversion that is performed by this
-- routine in OpenVMS mode.
- --------------------
- -- Cascaded_Error --
- --------------------
-
- procedure Cascaded_Error is
- begin
- -- An anomaly has been detected which is assumed to be a consequence of
- -- a previous error. Raise an exception if no serious error has been
- -- found so far.
-
- if Serious_Errors_Detected = 0 then
- raise Program_Error;
- end if;
- end Cascaded_Error;
-
-----------------------
-- Change_Error_Text --
-----------------------
diff --git a/gcc/ada/errout.ads b/gcc/ada/errout.ads
index 7da6493e453..2c6ab7d4ddd 100644
--- a/gcc/ada/errout.ads
+++ b/gcc/ada/errout.ads
@@ -39,19 +39,6 @@ with System;
package Errout is
- Serious_Errors_Detected : Nat renames Err_Vars.Serious_Errors_Detected;
- -- This is a count of errors that are serious enough to stop expansion,
- -- and hence to prevent generation of an object file even if the switch
- -- -gnatQ is set.
-
- Total_Errors_Detected : Nat renames Err_Vars.Total_Errors_Detected;
- -- Number of errors detected so far. Includes count of serious errors and
- -- non-serious errors, so this value is always greater than or equal to
- -- the Serious_Errors_Detected value.
-
- Warnings_Detected : Nat renames Err_Vars.Warnings_Detected;
- -- Number of warnings detected
-
Configurable_Run_Time_Violations : Nat := 0;
-- Count of configurable run time violations so far. This is used to
-- suppress certain cascaded error messages when we know that we may not
@@ -727,13 +714,6 @@ package Errout is
-- This routine can only be called during semantic analysis. It may not
-- be called during parsing.
- procedure Cascaded_Error;
- -- When an anomaly is detected, many semantic routines silently bail out,
- -- assuming that the anomaly was caused by a previously detected error.
- -- This routine should be called in these cases, and will raise an
- -- exception if no serious error has been detected. This ensure that the
- -- anomaly is never allowed to go unnoticed.
-
procedure Change_Error_Text (Error_Id : Error_Msg_Id; New_Msg : String);
-- The error message text of the message identified by Id is replaced by
-- the given text. This text may contain insertion characters in the
diff --git a/gcc/ada/erroutc.adb b/gcc/ada/erroutc.adb
index f58a49a8a5a..56a4e3547fb 100644
--- a/gcc/ada/erroutc.adb
+++ b/gcc/ada/erroutc.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2011, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -29,6 +29,7 @@
-- environment, and that in particular, no disallowed table expansion is
-- allowed to occur.
+with Atree; use Atree;
with Casing; use Casing;
with Debug; use Debug;
with Err_Vars; use Err_Vars;
diff --git a/gcc/ada/erroutc.ads b/gcc/ada/erroutc.ads
index 6c077b0f2e3..fc5cfa9fc21 100644
--- a/gcc/ada/erroutc.ads
+++ b/gcc/ada/erroutc.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 1992-2011, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
diff --git a/gcc/ada/errutil.adb b/gcc/ada/errutil.adb
index cf6e9ef2b3d..d6fa960a7a4 100644
--- a/gcc/ada/errutil.adb
+++ b/gcc/ada/errutil.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1991-2011, Free Software Foundation, Inc. --
+-- Copyright (C) 1991-2012, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -23,6 +23,7 @@
-- --
------------------------------------------------------------------------------
+with Atree; use Atree;
with Err_Vars; use Err_Vars;
with Erroutc; use Erroutc;
with Namet; use Namet;
diff --git a/gcc/ada/errutil.ads b/gcc/ada/errutil.ads
index 91ac4f1083b..fa6ad53b19d 100644
--- a/gcc/ada/errutil.ads
+++ b/gcc/ada/errutil.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 2002-2009, Free Software Foundation, Inc. --
+-- Copyright (C) 2002-2012, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -26,9 +26,7 @@
-- This package contains routines to output error messages and the
-- corresponding instantiation of Styleg, suitable to instantiate Scng.
--- It is not dependent on the GNAT tree packages (Atree, Sinfo, ...)
-
--- It uses the same global variables as Errout, located in package
+-- It uses the same global variables as Errout, located in packages Atree and
-- Err_Vars. Like Errout, it also uses the common variables and routines
-- in package Erroutc.
diff --git a/gcc/ada/eval_fat.adb b/gcc/ada/eval_fat.adb
index 8ebeb117614..d1c9d74859a 100644
--- a/gcc/ada/eval_fat.adb
+++ b/gcc/ada/eval_fat.adb
@@ -25,7 +25,7 @@
with Einfo; use Einfo;
with Errout; use Errout;
-with Targparm; use Targparm;
+with Sem_Util; use Sem_Util;
package body Eval_Fat is
@@ -57,20 +57,6 @@ package body Eval_Fat is
-- parts. The fraction is in the interval 1.0 / Radix .. T'Pred (1.0) and
-- uses Rbase = Radix. The result is rounded to a nearest machine number.
- procedure Decompose_Int
- (RT : R;
- X : T;
- Fraction : out UI;
- Exponent : out UI;
- Mode : Rounding_Mode);
- -- This is similar to Decompose, except that the Fraction value returned
- -- is an integer representing the value Fraction * Scale, where Scale is
- -- the value (Machine_Radix_Value (RT) ** Machine_Mantissa_Value (RT)). The
- -- value is obtained by using biased rounding (halfway cases round away
- -- from zero), round to even, a floor operation or a ceiling operation
- -- depending on the setting of Mode (see corresponding descriptions in
- -- Urealp).
-
--------------
-- Adjacent --
--------------
@@ -371,9 +357,14 @@ package body Eval_Fat is
case Mode is
when Round_Even =>
- -- This rounding mode should not be used for static
- -- expressions, but only for compile-time evaluation of
- -- non-static expressions.
+ -- This rounding mode corresponds to the unbiased rounding
+ -- method that is used at run time. When the real value is
+ -- exactly between two machine numbers, choose the machine
+ -- number with its least significant bit equal to zero.
+
+ -- The recommendation advice in RM 4.9(38) is that static
+ -- expressions are rounded to machine numbers in the same
+ -- way as the target machine does.
if (Even and then N * 2 > D)
or else
@@ -386,7 +377,9 @@ package body Eval_Fat is
-- Do not round to even as is done with IEEE arithmetic, but
-- instead round away from zero when the result is exactly
- -- between two machine numbers. See RM 4.9(38).
+ -- between two machine numbers. This biased rounding method
+ -- should not be used to convert static expressions to
+ -- machine numbers, see AI95-268.
if N * 2 >= D then
Fraction := Fraction + 1;
@@ -512,8 +505,8 @@ package body Eval_Fat is
Emin_Den : constant UI := Machine_Emin_Value (RT)
- Machine_Mantissa_Value (RT) + Uint_1;
begin
- if X_Exp < Emin_Den or not Denorm_On_Target then
- if UR_Is_Negative (X) then
+ if X_Exp < Emin_Den or not Has_Denormals (RT) then
+ if Has_Signed_Zeros (RT) and then UR_Is_Negative (X) then
Error_Msg_N
("floating-point value underflows to -0.0?", Enode);
return Ureal_M_0;
@@ -524,7 +517,7 @@ package body Eval_Fat is
return Ureal_0;
end if;
- elsif Denorm_On_Target then
+ elsif Has_Denormals (RT) then
-- Emin - Mant <= X_Exp < Emin, so result is denormal. Handle
-- gradual underflow by first computing the number of
@@ -725,7 +718,7 @@ package body Eval_Fat is
-- Set exponent such that the radix point will be directly following the
-- mantissa after scaling.
- if Denorm_On_Target or Exp /= Emin then
+ if Has_Denormals (RT) or Exp /= Emin then
Exp := Exp - Mantissa;
else
Exp := Exp - 1;
diff --git a/gcc/ada/eval_fat.ads b/gcc/ada/eval_fat.ads
index 964dd2224a5..4ef153ced77 100644
--- a/gcc/ada/eval_fat.ads
+++ b/gcc/ada/eval_fat.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 1992-2010, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -99,4 +99,18 @@ package Eval_Fat is
Mode : Rounding_Mode;
Enode : Node_Id) return T;
+ procedure Decompose_Int
+ (RT : R;
+ X : T;
+ Fraction : out UI;
+ Exponent : out UI;
+ Mode : Rounding_Mode);
+ -- Decomposes a floating-point number into fraction and exponent parts.
+ -- The Fraction value returned is an integer representing the value
+ -- Fraction * Scale, where Scale is the value (Machine_Radix_Value (RT) **
+ -- Machine_Mantissa_Value (RT)). The value is obtained by using biased
+ -- rounding (halfway cases round away from zero), round to even, a floor
+ -- operation or a ceiling operation depending on the setting of Mode (see
+ -- corresponding descriptions in Urealp).
+
end Eval_Fat;
diff --git a/gcc/ada/exp_attr.adb b/gcc/ada/exp_attr.adb
index 1b50d293f8c..dcaac0c29b9 100644
--- a/gcc/ada/exp_attr.adb
+++ b/gcc/ada/exp_attr.adb
@@ -27,6 +27,7 @@ with Atree; use Atree;
with Checks; use Checks;
with Einfo; use Einfo;
with Elists; use Elists;
+with Errout; use Errout;
with Exp_Atag; use Exp_Atag;
with Exp_Ch2; use Exp_Ch2;
with Exp_Ch3; use Exp_Ch3;
@@ -2953,7 +2954,7 @@ package body Exp_Attr is
-- Length --
------------
- when Attribute_Length => declare
+ when Attribute_Length => Length : declare
Ityp : Entity_Id;
Xnum : Uint;
@@ -3103,7 +3104,13 @@ package body Exp_Attr is
else
Apply_Universal_Integer_Attribute_Checks (N);
end if;
- end;
+ end Length;
+
+ -- The expansion of this attribute is carried out when the target loop
+ -- is processed. See Expand_Loop_Entry_Attributes for details.
+
+ when Attribute_Loop_Entry =>
+ null;
-------------
-- Machine --
@@ -5602,6 +5609,35 @@ package body Exp_Attr is
Rewrite (N, Make_Range_Test);
end if;
+ -- If a predicate is present, then we do the predicate test, even if
+ -- within the predicate function (infinite recursion is warned about
+ -- in that case).
+
+ declare
+ Pred_Func : constant Entity_Id := Predicate_Function (Ptyp);
+
+ begin
+ if Present (Pred_Func) then
+ Rewrite (N,
+ Make_And_Then (Loc,
+ Left_Opnd => Relocate_Node (N),
+ Right_Opnd => Make_Predicate_Call (Ptyp, Pref)));
+
+ -- If the attribute appears within the subtype's own predicate
+ -- function, then issue a warning that this will cause infinite
+ -- recursion.
+
+ -- Do we have to issue these warnings in the expander rather
+ -- than during analysis (means they are skipped in -gnatc???).
+
+ if Current_Scope = Pred_Func then
+ Error_Msg_N
+ ("attribute Valid requires a predicate check?", N);
+ Error_Msg_N ("\and will result in infinite recursion?", N);
+ end if;
+ end if;
+ end;
+
Analyze_And_Resolve (N, Standard_Boolean);
Validity_Checks_On := Save_Validity_Checks_On;
end Valid;
diff --git a/gcc/ada/exp_ch13.adb b/gcc/ada/exp_ch13.adb
index 26eaec28b4e..141e144ab5b 100644
--- a/gcc/ada/exp_ch13.adb
+++ b/gcc/ada/exp_ch13.adb
@@ -379,6 +379,7 @@ package body Exp_Ch13 is
-- This is an error protection against previous errors
if No (E_Scope) then
+ Check_Error_Detected;
return;
end if;
diff --git a/gcc/ada/exp_ch2.adb b/gcc/ada/exp_ch2.adb
index 37a5bda6527..b93f832441c 100644
--- a/gcc/ada/exp_ch2.adb
+++ b/gcc/ada/exp_ch2.adb
@@ -28,11 +28,9 @@ with Checks; use Checks;
with Debug; use Debug;
with Einfo; use Einfo;
with Elists; use Elists;
-with Errout; use Errout;
with Exp_Smem; use Exp_Smem;
with Exp_Tss; use Exp_Tss;
with Exp_Util; use Exp_Util;
-with Exp_VFpt; use Exp_VFpt;
with Namet; use Namet;
with Nmake; use Nmake;
with Opt; use Opt;
@@ -342,7 +340,8 @@ package body Exp_Ch2 is
begin
-- Defend against errors
- if No (E) and then Total_Errors_Detected /= 0 then
+ if No (E) then
+ Check_Error_Detected;
return;
end if;
@@ -636,10 +635,14 @@ package body Exp_Ch2 is
---------------------------
procedure Expand_N_Real_Literal (N : Node_Id) is
+ pragma Unreferenced (N);
+
begin
- if Vax_Float (Etype (N)) then
- Expand_Vax_Real_Literal (N);
- end if;
+ -- Historically, this routine existed because there were expansion
+ -- requirements for Vax real literals, but now Vax real literals
+ -- are now handled by gigi, so this routine no longer does anything.
+
+ null;
end Expand_N_Real_Literal;
--------------------------------
diff --git a/gcc/ada/exp_ch3.adb b/gcc/ada/exp_ch3.adb
index f7081a6480d..2434d5b7d95 100644
--- a/gcc/ada/exp_ch3.adb
+++ b/gcc/ada/exp_ch3.adb
@@ -1537,10 +1537,10 @@ package body Exp_Ch3 is
Append_To (Args, Make_Identifier (Loc, Name_uMaster));
end if;
- -- Add _Chain (not done in the restricted profile because not used,
- -- see comment for Create_Restricted_Task in s-tarest.ads).
+ -- Add _Chain (not done for sequential elaboration policy, see
+ -- comment for Create_Restricted_Task_Sequential in s-tarest.ads).
- if not Restricted_Profile then
+ if Partition_Elaboration_Policy /= 'S' then
Append_To (Args, Make_Identifier (Loc, Name_uChain));
end if;
@@ -2004,11 +2004,10 @@ package body Exp_Ch3 is
Append_To (Args, Make_Identifier (Loc, Name_uMaster));
end if;
- if not Restricted_Profile then
-
- -- No _Chain for the restricted profile because not used,
- -- see comment of Create_Restricted_Task in s-tarest.ads.
+ -- Add _Chain (not done for sequential elaboration policy, see
+ -- comment for Create_Restricted_Task_Sequential in s-tarest.ads).
+ if Partition_Elaboration_Policy /= 'S' then
Append_To (Args, Make_Identifier (Loc, Name_uChain));
end if;
@@ -7793,11 +7792,10 @@ package body Exp_Ch3 is
Parameter_Type =>
New_Reference_To (RTE (RE_Master_Id), Loc)));
- if not Restricted_Profile then
-
- -- No _Chain for the restricted profile because not used, see
- -- comment for Create_Restricted_Task in s-tarest.ads.
+ -- Add _Chain (not done for sequential elaboration policy, see
+ -- comment for Create_Restricted_Task_Sequential in s-tarest.ads).
+ if Partition_Elaboration_Policy /= 'S' then
Append_To (Formals,
Make_Parameter_Specification (Loc,
Defining_Identifier =>
diff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb
index ebdbcdeb316..bf3a6479761 100644
--- a/gcc/ada/exp_ch4.adb
+++ b/gcc/ada/exp_ch4.adb
@@ -213,19 +213,19 @@ package body Exp_Ch4 is
-- Convert_To_Actual_Subtype if necessary).
function Minimized_Eliminated_Overflow_Check (N : Node_Id) return Boolean;
- -- For signed arithmetic operations with Do_Overflow_Check set when the
- -- current overflow mode is MINIMIZED or ELIMINATED, we need to make a
- -- call to Apply_Arithmetic_Overflow_Checks as the first thing we do. We
- -- then return. We count on the recursive apparatus for overflow checks
- -- to call us back with an equivalent operation that does not have the
- -- Do_Overflow_Check flag set, and that is when we will proceed with the
- -- expansion of the operator (e.g. converting X+0 to X, or X**2 to X*X).
- -- We cannot do these optimizations without first making this check, since
- -- there may be operands further down the tree that are relying on the
- -- recursive calls triggered by the top level nodes to properly process
- -- overflow checking and remaining expansion on these nodes. Note that
- -- this call back may be skipped if the operation is done in Bignum mode
- -- but that's fine, since the Bignum call takes care of everything.
+ -- For signed arithmetic operations when the current overflow mode is
+ -- MINIMIZED or ELIMINATED, we must call Apply_Arithmetic_Overflow_Checks
+ -- as the first thing we do. We then return. We count on the recursive
+ -- apparatus for overflow checks to call us back with an equivalent
+ -- operation that is in CHECKED mode, avoiding a recursive entry into this
+ -- routine, and that is when we will proceed with the expansion of the
+ -- operator (e.g. converting X+0 to X, or X**2 to X*X). We cannot do
+ -- these optimizations without first making this check, since there may be
+ -- operands further down the tree that are relying on the recursive calls
+ -- triggered by the top level nodes to properly process overflow checking
+ -- and remaining expansion on these nodes. Note that this call back may be
+ -- skipped if the operation is done in Bignum mode but that's fine, since
+ -- the Bignum call takes care of everything.
procedure Optimize_Length_Comparison (N : Node_Id);
-- Given an expression, if it is of the form X'Length op N (or the other
@@ -2274,8 +2274,8 @@ package body Exp_Ch4 is
LLIB : constant Entity_Id := Base_Type (Standard_Long_Long_Integer);
-- Entity for Long_Long_Integer'Base
- Check : constant Overflow_Check_Type := Overflow_Check_Mode (Empty);
- -- Current checking mode
+ Check : constant Overflow_Check_Type := Overflow_Check_Mode;
+ -- Current overflow checking mode
procedure Set_True;
procedure Set_False;
@@ -2320,9 +2320,9 @@ package body Exp_Ch4 is
-- our operands using the Minimize_Eliminate circuitry which applies
-- this processing to the two operand subtrees.
- Minimize_Eliminate_Overflow_Checks
+ Minimize_Eliminate_Overflows
(Left_Opnd (N), Llo, Lhi, Top_Level => False);
- Minimize_Eliminate_Overflow_Checks
+ Minimize_Eliminate_Overflows
(Right_Opnd (N), Rlo, Rhi, Top_Level => False);
-- See if the range information decides the result of the comparison.
@@ -3715,13 +3715,13 @@ package body Exp_Ch4 is
-- Save result type
Lo, Hi : Uint;
- -- Bounds in Minimize calls, not used yet ???
+ -- Bounds in Minimize calls, not used currently
LLIB : constant Entity_Id := Base_Type (Standard_Long_Long_Integer);
-- Entity for Long_Long_Integer'Base (Standard should export this???)
begin
- Minimize_Eliminate_Overflow_Checks (Lop, Lo, Hi, Top_Level => False);
+ Minimize_Eliminate_Overflows (Lop, Lo, Hi, Top_Level => False);
-- If right operand is a subtype name, and the subtype name has no
-- predicate, then we can just replace the right operand with an
@@ -3751,9 +3751,9 @@ package body Exp_Ch4 is
-- have not been processed for minimized or eliminated checks.
if Nkind (Rop) = N_Range then
- Minimize_Eliminate_Overflow_Checks
+ Minimize_Eliminate_Overflows
(Low_Bound (Rop), Lo, Hi, Top_Level => False);
- Minimize_Eliminate_Overflow_Checks
+ Minimize_Eliminate_Overflows
(High_Bound (Rop), Lo, Hi, Top_Level => False);
-- We have A in B .. C, treated as A >= B and then A <= C
@@ -5498,7 +5498,7 @@ package body Exp_Ch4 is
-- in which case, this usage makes sense, and in any case, we have
-- actually eliminated the danger of optimization above.
- if Overflow_Check_Mode (Restyp) not in Minimized_Or_Eliminated then
+ if Overflow_Check_Mode not in Minimized_Or_Eliminated then
Error_Msg_N ("?explicit membership test may be optimized away", N);
Error_Msg_N -- CODEFIX
("\?use ''Valid attribute instead", N);
@@ -5526,7 +5526,7 @@ package body Exp_Ch4 is
-- type, then expand with a separate procedure. Note the use of the
-- flag No_Minimize_Eliminate to prevent infinite recursion.
- if Overflow_Check_Mode (Empty) in Minimized_Or_Eliminated
+ if Overflow_Check_Mode in Minimized_Or_Eliminated
and then Is_Signed_Integer_Type (Ltyp)
and then not No_Minimize_Eliminate (N)
then
@@ -5565,8 +5565,7 @@ package body Exp_Ch4 is
-- Skip this for predicated types, where such expressions are a
-- reasonable way of testing if something meets the predicate.
- and then not (Is_Discrete_Type (Ltyp)
- and then Present (Predicate_Function (Ltyp)))
+ and then not Present (Predicate_Function (Ltyp))
then
Substitute_Valid_Check;
return;
@@ -6103,6 +6102,9 @@ package body Exp_Ch4 is
-- If a predicate is present, then we do the predicate test, but we
-- most certainly want to omit this if we are within the predicate
-- function itself, since otherwise we have an infinite recursion!
+ -- The check should also not be emitted when testing against a range
+ -- (the check is only done when the right operand is a subtype; see
+ -- RM12-4.5.2 (28.1/3-30/3)).
declare
PFunc : constant Entity_Id := Predicate_Function (Rtyp);
@@ -6110,6 +6112,7 @@ package body Exp_Ch4 is
begin
if Present (PFunc)
and then Current_Scope /= PFunc
+ and then Nkind (Rop) /= N_Range
then
Rewrite (N,
Make_And_Then (Loc,
@@ -11782,8 +11785,7 @@ package body Exp_Ch4 is
begin
return
Is_Signed_Integer_Type (Etype (N))
- and then Do_Overflow_Check (N)
- and then Overflow_Check_Mode (Empty) in Minimized_Or_Eliminated;
+ and then Overflow_Check_Mode in Minimized_Or_Eliminated;
end Minimized_Eliminated_Overflow_Check;
--------------------------------
diff --git a/gcc/ada/exp_ch5.adb b/gcc/ada/exp_ch5.adb
index e9ec75ed003..80aabc5acd8 100644
--- a/gcc/ada/exp_ch5.adb
+++ b/gcc/ada/exp_ch5.adb
@@ -28,6 +28,7 @@ with Atree; use Atree;
with Checks; use Checks;
with Debug; use Debug;
with Einfo; use Einfo;
+with Elists; use Elists;
with Errout; use Errout;
with Exp_Aggr; use Exp_Aggr;
with Exp_Ch6; use Exp_Ch6;
@@ -110,6 +111,10 @@ package body Exp_Ch5 is
procedure Expand_Iterator_Loop_Over_Array (N : Node_Id);
-- Expand loop over arrays that uses the form "for X of C"
+ procedure Expand_Loop_Entry_Attributes (N : Node_Id);
+ -- Given a loop statement subject to at least one Loop_Entry attribute,
+ -- expand both the loop and all related Loop_Entry references.
+
procedure Expand_Predicated_Loop (N : Node_Id);
-- Expand for loop over predicated subtype
@@ -1522,6 +1527,324 @@ package body Exp_Ch5 is
end;
end Expand_Assign_Record;
+ ----------------------------------
+ -- Expand_Loop_Entry_Attributes --
+ ----------------------------------
+
+ procedure Expand_Loop_Entry_Attributes (N : Node_Id) is
+ procedure Build_Conditional_Block
+ (Loc : Source_Ptr;
+ Cond : Node_Id;
+ Stmt : Node_Id;
+ If_Stmt : out Node_Id;
+ Blk_Stmt : out Node_Id);
+ -- Create a block Blk_Stmt with an empty declarative list and a single
+ -- statement Stmt. The block is encased in an if statement If_Stmt with
+ -- condition Cond. If_Stmt is Empty when there is no condition provided.
+
+ function Is_Array_Iteration (N : Node_Id) return Boolean;
+ -- Determine whether loop statement N denotes an Ada 2012 iteration over
+ -- an array object.
+
+ -----------------------------
+ -- Build_Conditional_Block --
+ -----------------------------
+
+ procedure Build_Conditional_Block
+ (Loc : Source_Ptr;
+ Cond : Node_Id;
+ Stmt : Node_Id;
+ If_Stmt : out Node_Id;
+ Blk_Stmt : out Node_Id)
+ is
+ begin
+ Blk_Stmt :=
+ Make_Block_Statement (Loc,
+ Declarations => New_List,
+ Handled_Statement_Sequence =>
+ Make_Handled_Sequence_Of_Statements (Loc,
+ Statements => New_List (Stmt)));
+
+ if Present (Cond) then
+ If_Stmt :=
+ Make_If_Statement (Loc,
+ Condition => Cond,
+ Then_Statements => New_List (Blk_Stmt));
+ else
+ If_Stmt := Empty;
+ end if;
+ end Build_Conditional_Block;
+
+ ------------------------
+ -- Is_Array_Iteration --
+ ------------------------
+
+ function Is_Array_Iteration (N : Node_Id) return Boolean is
+ Stmt : constant Node_Id := Original_Node (N);
+ Iter : Node_Id;
+
+ begin
+ if Nkind (Stmt) = N_Loop_Statement
+ and then Present (Iteration_Scheme (Stmt))
+ and then Present (Iterator_Specification (Iteration_Scheme (Stmt)))
+ then
+ Iter := Iterator_Specification (Iteration_Scheme (Stmt));
+
+ return
+ Of_Present (Iter)
+ and then Is_Array_Type (Etype (Name (Iter)));
+ end if;
+
+ return False;
+ end Is_Array_Iteration;
+
+ -- Local variables
+
+ Loc : constant Source_Ptr := Sloc (N);
+ Loop_Id : constant Entity_Id := Identifier (N);
+ Scheme : constant Node_Id := Iteration_Scheme (N);
+ Blk : Node_Id;
+ LE : Node_Id;
+ LE_Elmt : Elmt_Id;
+ Result : Node_Id;
+ Temp : Entity_Id;
+ Typ : Entity_Id;
+
+ -- Start of processing for Expand_Loop_Entry_Attributes
+
+ begin
+ -- The loop will never execute after it has been expanded, no point in
+ -- processing it.
+
+ if Is_Null_Loop (N) then
+ return;
+
+ -- A loop without an identifier cannot be referenced in 'Loop_Entry
+
+ elsif No (Loop_Id) then
+ return;
+
+ -- The loop is not subject to 'Loop_Entry
+
+ elsif No (Loop_Entry_Attributes (Entity (Loop_Id))) then
+ return;
+
+ -- Step 1: Loop transformations
+
+ -- While loops are transformed into:
+
+ -- if <Condition> then
+ -- declare
+ -- Temp1 : constant <type of Pref1> := <Pref1>;
+ -- . . .
+ -- TempN : constant <type of PrefN> := <PrefN>;
+ -- begin
+ -- loop
+ -- <original source statements with attribute rewrites>
+ -- exit when not <Condition>;
+ -- end loop;
+ -- end;
+ -- end if;
+
+ -- Note that loops over iterators and containers are already converted
+ -- into while loops.
+
+ elsif Present (Condition (Scheme)) then
+ declare
+ Cond : constant Node_Id := Condition (Scheme);
+
+ begin
+ -- Transform the original while loop into an infinite loop where
+ -- the last statement checks the negated condition. This placement
+ -- ensures that the condition will not be evaluated twice on the
+ -- first iteration.
+
+ -- Generate:
+ -- exit when not <Cond>:
+
+ Append_To (Statements (N),
+ Make_Exit_Statement (Loc,
+ Condition => Make_Op_Not (Loc, New_Copy_Tree (Cond))));
+
+ Build_Conditional_Block (Loc,
+ Cond => Relocate_Node (Cond),
+ Stmt => Relocate_Node (N),
+ If_Stmt => Result,
+ Blk_Stmt => Blk);
+ end;
+
+ -- Ada 2012 iteration over an array is transformed into:
+
+ -- if <Array_Nam>'Length (1) > 0
+ -- and then <Array_Nam>'Length (N) > 0
+ -- then
+ -- declare
+ -- Temp1 : constant <type of Pref1> := <Pref1>;
+ -- . . .
+ -- TempN : constant <type of PrefN> := <PrefN>;
+ -- begin
+ -- for X in ... loop -- multiple loops depending on dims
+ -- <original source statements with attribute rewrites>
+ -- end loop;
+ -- end;
+ -- end if;
+
+ elsif Is_Array_Iteration (N) then
+ declare
+ Array_Nam : constant Entity_Id :=
+ Entity (Name (Iterator_Specification
+ (Iteration_Scheme (Original_Node (N)))));
+ Num_Dims : constant Pos :=
+ Number_Dimensions (Etype (Array_Nam));
+ Cond : Node_Id := Empty;
+ Check : Node_Id;
+ Top_Loop : Node_Id;
+
+ begin
+ -- Generate a check which determines whether all dimensions of
+ -- the array are non-null.
+
+ for Dim in 1 .. Num_Dims loop
+ Check :=
+ Make_Op_Gt (Loc,
+ Left_Opnd =>
+ Make_Attribute_Reference (Loc,
+ Prefix => New_Reference_To (Array_Nam, Loc),
+ Attribute_Name => Name_Length,
+ Expressions => New_List (
+ Make_Integer_Literal (Loc, Dim))),
+ Right_Opnd =>
+ Make_Integer_Literal (Loc, 0));
+
+ if No (Cond) then
+ Cond := Check;
+ else
+ Cond :=
+ Make_And_Then (Loc,
+ Left_Opnd => Cond,
+ Right_Opnd => Check);
+ end if;
+ end loop;
+
+ Top_Loop := Relocate_Node (N);
+ Set_Analyzed (Top_Loop);
+
+ Build_Conditional_Block (Loc,
+ Cond => Cond,
+ Stmt => Top_Loop,
+ If_Stmt => Result,
+ Blk_Stmt => Blk);
+ end;
+
+ -- For loops are transformed into:
+
+ -- if <Low> <= <High> then
+ -- declare
+ -- Temp1 : constant <type of Pref1> := <Pref1>;
+ -- . . .
+ -- TempN : constant <type of PrefN> := <PrefN>;
+ -- begin
+ -- for <Def_Id> in <Low> .. <High> loop
+ -- <original source statements with attribute rewrites>
+ -- end loop;
+ -- end;
+ -- end if;
+
+ elsif Present (Loop_Parameter_Specification (Scheme)) then
+ declare
+ Loop_Spec : constant Node_Id :=
+ Loop_Parameter_Specification (Scheme);
+ Subt_Def : constant Node_Id :=
+ Discrete_Subtype_Definition (Loop_Spec);
+ Cond : Node_Id;
+
+ begin
+ -- At this point in the expansion all discrete subtype definitions
+ -- should be transformed into ranges.
+
+ pragma Assert (Nkind (Subt_Def) = N_Range);
+
+ -- Generate
+ -- Low <= High
+
+ Cond :=
+ Make_Op_Le (Loc,
+ Left_Opnd => New_Copy_Tree (Low_Bound (Subt_Def)),
+ Right_Opnd => New_Copy_Tree (High_Bound (Subt_Def)));
+
+ Build_Conditional_Block (Loc,
+ Cond => Cond,
+ Stmt => Relocate_Node (N),
+ If_Stmt => Result,
+ Blk_Stmt => Blk);
+ end;
+
+ -- Infinite loops are transformed into:
+
+ -- declare
+ -- Temp1 : constant <type of Pref1> := <Pref1>;
+ -- . . .
+ -- TempN : constant <type of PrefN> := <PrefN>;
+ -- begin
+ -- loop
+ -- <original source statements with attribute rewrites>
+ -- end loop;
+ -- end;
+
+ else
+ Build_Conditional_Block (Loc,
+ Cond => Empty,
+ Stmt => Relocate_Node (N),
+ If_Stmt => Result,
+ Blk_Stmt => Blk);
+
+ Result := Blk;
+ end if;
+
+ -- Step 2: Loop_Entry attribute transformations
+
+ -- At this point the various loops have been augmented to contain a
+ -- block. Populate the declarative list of the block with constants
+ -- which store the value of their relative prefixes at the point of
+ -- entry in the loop.
+
+ LE_Elmt := First_Elmt (Loop_Entry_Attributes (Entity (Loop_Id)));
+ while Present (LE_Elmt) loop
+ LE := Node (LE_Elmt);
+ Typ := Etype (Prefix (LE));
+
+ -- Declare a constant to capture the value of the previx of each
+ -- Loop_Entry attribute.
+
+ -- Generate:
+ -- Temp : constant <type of Pref> := <Pref>;
+
+ Temp := Make_Temporary (Loc, 'P');
+
+ Append_To (Declarations (Blk),
+ Make_Object_Declaration (Loc,
+ Defining_Identifier => Temp,
+ Constant_Present => True,
+ Object_Definition => New_Reference_To (Typ, Loc),
+ Expression => Relocate_Node (Prefix (LE))));
+
+ -- Replace the original attribute with a reference to the constant
+
+ Rewrite (LE, New_Reference_To (Temp, Loc));
+ Set_Etype (LE, Typ);
+
+ Next_Elmt (LE_Elmt);
+ end loop;
+
+ -- Destroy the list of Loop_Entry attributes to prevent the infinite
+ -- expansion when analyzing and expanding the newly generated loops.
+
+ Set_Loop_Entry_Attributes (Entity (Loop_Id), No_Elist);
+
+ Rewrite (N, Result);
+ Analyze (N);
+ end Expand_Loop_Entry_Attributes;
+
-----------------------------------
-- Expand_N_Assignment_Statement --
-----------------------------------
@@ -3108,6 +3431,11 @@ package body Exp_Ch5 is
Expressions =>
New_List (New_Occurrence_Of (Cursor, Loc))));
+ -- The defining identifier in the iterator is user-visible
+ -- and must be visible in the debugger.
+
+ Set_Debug_Info_Needed (Id);
+
-- If the container holds controlled objects, wrap the loop
-- statements and element renaming declaration with a block.
-- This ensures that the result of Element (Cusor) is
@@ -3657,6 +3985,13 @@ package body Exp_Ch5 is
then
Expand_Iterator_Loop (N);
end if;
+
+ -- If the loop is subject to at least one Loop_Entry attribute, it
+ -- requires additional processing.
+
+ if Nkind (N) = N_Loop_Statement then
+ Expand_Loop_Entry_Attributes (N);
+ end if;
end Expand_N_Loop_Statement;
----------------------------
@@ -3849,10 +4184,10 @@ package body Exp_Ch5 is
-- Rewrite the loop
D :=
- Make_Object_Declaration (Loc,
- Defining_Identifier => Loop_Id,
- Object_Definition => New_Occurrence_Of (Ltype, Loc),
- Expression => Lo_Val (First (Stat)));
+ Make_Object_Declaration (Loc,
+ Defining_Identifier => Loop_Id,
+ Object_Definition => New_Occurrence_Of (Ltype, Loc),
+ Expression => Lo_Val (First (Stat)));
Set_Suppress_Assignment_Checks (D);
Rewrite (N,
diff --git a/gcc/ada/exp_ch6.adb b/gcc/ada/exp_ch6.adb
index 8d9ef9b38dd..c3cf8c8e70b 100644
--- a/gcc/ada/exp_ch6.adb
+++ b/gcc/ada/exp_ch6.adb
@@ -6227,6 +6227,7 @@ package body Exp_Ch6 is
if Present (Expression (N))
and then Nkind (Expression (N)) = N_Empty
then
+ Check_Error_Detected;
return;
end if;
diff --git a/gcc/ada/exp_ch9.adb b/gcc/ada/exp_ch9.adb
index 82a7a309c72..781de8695dc 100644
--- a/gcc/ada/exp_ch9.adb
+++ b/gcc/ada/exp_ch9.adb
@@ -911,10 +911,10 @@ package body Exp_Ch9 is
-- Start of processing for Build_Activation_Chain_Entity
begin
- -- Activation chain is never used in restricted profile, see comment
- -- for Create_Restricted_Task in s-tarest.ads.
+ -- Activation chain is never used for sequential elaboration policy, see
+ -- comment for Create_Restricted_Task_Sequential in s-tarest.ads).
- if Restricted_Profile then
+ if Partition_Elaboration_Policy = 'S' then
return;
end if;
@@ -4900,10 +4900,10 @@ package body Exp_Ch9 is
P : Node_Id;
begin
- -- On restricted profile, all the tasks will be activated at the end
- -- of the elaboration (Sequential elaboration policy).
+ -- For sequential elaboration policy, all the tasks will be activated at
+ -- the end of the elaboration.
- if Restricted_Profile then
+ if Partition_Elaboration_Policy = 'S' then
return;
end if;
@@ -4925,7 +4925,11 @@ package body Exp_Ch9 is
end if;
if Present (Chain) then
- Name := New_Reference_To (RTE (RE_Activate_Tasks), Loc);
+ if Restricted_Profile then
+ Name := New_Reference_To (RTE (RE_Activate_Restricted_Tasks), Loc);
+ else
+ Name := New_Reference_To (RTE (RE_Activate_Tasks), Loc);
+ end if;
Call :=
Make_Procedure_Call_Statement (Loc,
@@ -13980,10 +13984,10 @@ package body Exp_Ch9 is
Prefix => Make_Identifier (Loc, New_External_Name (Tnam, 'E')),
Attribute_Name => Name_Unchecked_Access));
- -- Chain parameter. This is a reference to the Chain parameter of the
- -- initialization procedure. There is no chain in restricted profile.
+ -- Add Chain parameter (not done for sequential elaboration policy, see
+ -- comment for Create_Restricted_Task_Sequential in s-tarest.ads).
- if not Restricted_Profile then
+ if Partition_Elaboration_Policy /= 'S' then
Append_To (Args, Make_Identifier (Loc, Name_uChain));
end if;
@@ -14015,11 +14019,22 @@ package body Exp_Ch9 is
Prefix => Make_Identifier (Loc, Name_uInit),
Selector_Name => Make_Identifier (Loc, Name_uTask_Id)));
- if Restricted_Profile then
- Name := New_Reference_To (RTE (RE_Create_Restricted_Task), Loc);
- else
- Name := New_Reference_To (RTE (RE_Create_Task), Loc);
- end if;
+ declare
+ Create_RE : RE_Id;
+
+ begin
+ if Restricted_Profile then
+ if Partition_Elaboration_Policy = 'S' then
+ Create_RE := RE_Create_Restricted_Task_Sequential;
+ else
+ Create_RE := RE_Create_Restricted_Task;
+ end if;
+ else
+ Create_RE := RE_Create_Task;
+ end if;
+
+ Name := New_Reference_To (RTE (Create_RE), Loc);
+ end;
return
Make_Procedure_Call_Statement (Loc,
diff --git a/gcc/ada/exp_dbug.adb b/gcc/ada/exp_dbug.adb
index 9267982f85f..c034fe5cf6b 100644
--- a/gcc/ada/exp_dbug.adb
+++ b/gcc/ada/exp_dbug.adb
@@ -1307,12 +1307,13 @@ package body Exp_Dbug is
if Has_Qualified_Name (Ent) then
return;
- -- In formal verification mode, simply append a suffix for homonyms, but
- -- do not mark the name as being qualified. We used to qualify entity
- -- names as full expansion does, but this was removed as this prevents
- -- the verification back-end from using a short name for debugging and
- -- user interaction. The verification back-end already takes care of
- -- qualifying names when needed.
+ -- In formal verification mode, simply append a suffix for homonyms.
+ -- We used to qualify entity names as full expansion does, but this was
+ -- removed as this prevents the verification back-end from using a short
+ -- name for debugging and user interaction. The verification back-end
+ -- already takes care of qualifying names when needed. Still mark the
+ -- name as being qualified, as Qualify_Entity_Name may be called more
+ -- than once on the same entity.
elsif Alfa_Mode then
if Has_Homonym (Ent) then
@@ -1322,6 +1323,7 @@ package body Exp_Dbug is
Set_Chars (Ent, Name_Enter);
end if;
+ Set_Has_Qualified_Name (Ent);
return;
-- If the entity is a variable encoding the debug name for an object
diff --git a/gcc/ada/exp_dist.adb b/gcc/ada/exp_dist.adb
index cf8243e9ca7..c2396c1e568 100644
--- a/gcc/ada/exp_dist.adb
+++ b/gcc/ada/exp_dist.adb
@@ -26,7 +26,6 @@
with Atree; use Atree;
with Einfo; use Einfo;
with Elists; use Elists;
-with Errout; use Errout;
with Exp_Atag; use Exp_Atag;
with Exp_Disp; use Exp_Disp;
with Exp_Strm; use Exp_Strm;
diff --git a/gcc/ada/exp_prag.adb b/gcc/ada/exp_prag.adb
index 469cb8379fc..c21c21c5c80 100644
--- a/gcc/ada/exp_prag.adb
+++ b/gcc/ada/exp_prag.adb
@@ -39,6 +39,7 @@ with Restrict; use Restrict;
with Rident; use Rident;
with Rtsfind; use Rtsfind;
with Sem; use Sem;
+with Sem_Ch8; use Sem_Ch8;
with Sem_Res; use Sem_Res;
with Sem_Util; use Sem_Util;
with Sinfo; use Sinfo;
@@ -68,6 +69,7 @@ package body Exp_Prag is
procedure Expand_Pragma_Import_Export_Exception (N : Node_Id);
procedure Expand_Pragma_Inspection_Point (N : Node_Id);
procedure Expand_Pragma_Interrupt_Priority (N : Node_Id);
+ procedure Expand_Pragma_Loop_Assertion (N : Node_Id);
procedure Expand_Pragma_Psect_Object (N : Node_Id);
procedure Expand_Pragma_Relative_Deadline (N : Node_Id);
@@ -189,6 +191,9 @@ package body Exp_Prag is
when Pragma_Interrupt_Priority =>
Expand_Pragma_Interrupt_Priority (N);
+ when Pragma_Loop_Assertion =>
+ Expand_Pragma_Loop_Assertion (N);
+
when Pragma_Psect_Object =>
Expand_Pragma_Psect_Object (N);
@@ -790,6 +795,400 @@ package body Exp_Prag is
end if;
end Expand_Pragma_Interrupt_Priority;
+ ----------------------------------
+ -- Expand_Pragma_Loop_Assertion --
+ ----------------------------------
+
+ -- Pragma Loop_Assertion is expanded in the following manner:
+
+ -- Original code
+
+ -- for | while ... loop
+ -- <preceding source statements>
+ -- pragma Loop_Assertion
+ -- (Invariant => Invar_Expr,
+ -- Variant => (Increasing => Incr_Expr,
+ -- Decreasing => Decr_Expr));
+ -- <succeeding source statements>
+ -- end loop;
+
+ -- Expanded code
+
+ -- Curr_1 : <type of Incr_Expr>;
+ -- Curr_2 : <type of Decr_Expr>;
+ -- Old_1 : <type of Incr_Expr>;
+ -- Old_2 : <type of Decr_Expr>;
+ -- Flag : Boolean := False;
+
+ -- for | while ... loop
+ -- <preceding source statements>
+
+ -- pragma Assert (<Invar_Expr>);
+
+ -- if Flag then
+ -- Old_1 := Curr_1;
+ -- Old_2 := Curr_2;
+ -- end if;
+
+ -- Curr_1 := <Incr_Expr>;
+ -- Curr_2 := <Decr_Expr>;
+
+ -- if Flag then
+ -- if Curr_1 /= Old_1 then
+ -- pragma Assert (Curr_1 > Old_1);
+ -- else
+ -- pragma Assert (Curr_2 < Old_2);
+ -- end if;
+ -- else
+ -- Flag := True;
+ -- end if;
+
+ -- <succeeding source statements>
+ -- end loop;
+
+ procedure Expand_Pragma_Loop_Assertion (N : Node_Id) is
+ Loc : constant Source_Ptr := Sloc (N);
+ Curr_Assign : List_Id := No_List;
+ Flag_Id : Entity_Id := Empty;
+ If_Stmt : Node_Id := Empty;
+ Loop_Scop : Entity_Id;
+ Loop_Stmt : Node_Id;
+ Old_Assign : List_Id := No_List;
+
+ procedure Process_Increase_Decrease
+ (Variant : Node_Id;
+ Is_Last : Boolean);
+ -- Process a single increasing / decreasing termination variant. Flag
+ -- Is_Last should be set when processing the last variant.
+
+ -------------------------------
+ -- Process_Increase_Decrease --
+ -------------------------------
+
+ procedure Process_Increase_Decrease
+ (Variant : Node_Id;
+ Is_Last : Boolean)
+ is
+ function Make_Op
+ (Loc : Source_Ptr;
+ Curr_Val : Node_Id;
+ Old_Val : Node_Id) return Node_Id;
+ -- Generate a comparison between Curr_Val and Old_Val depending on
+ -- the argument name (Increases / Decreases).
+
+ -------------
+ -- Make_Op --
+ -------------
+
+ function Make_Op
+ (Loc : Source_Ptr;
+ Curr_Val : Node_Id;
+ Old_Val : Node_Id) return Node_Id
+ is
+ Modif : constant Node_Id := First (Choices (Variant));
+ begin
+ if Chars (Modif) = Name_Increasing then
+ return Make_Op_Gt (Loc, Curr_Val, Old_Val);
+
+ else pragma Assert (Chars (Modif) = Name_Decreasing);
+ return Make_Op_Lt (Loc, Curr_Val, Old_Val);
+ end if;
+ end Make_Op;
+
+ -- Local variables
+
+ Expr : constant Node_Id := Expression (Variant);
+ Loc : constant Source_Ptr := Sloc (Expr);
+ Loop_Loc : constant Source_Ptr := Sloc (Loop_Stmt);
+ Curr_Id : Entity_Id;
+ Old_Id : Entity_Id;
+ Prag : Node_Id;
+
+ -- Start of processing for Process_Increase_Decrease
+
+ begin
+ -- All temporaries generated in this routine must be inserted before
+ -- the related loop statement. Ensure that the proper scope is on the
+ -- stack when analyzing the temporaries. Note that we also use the
+ -- Sloc of the related loop.
+
+ Push_Scope (Scope (Loop_Scop));
+
+ -- Step 1: Create the declaration of the flag which controls the
+ -- behavior of the assertion on the first iteration of the loop.
+
+ if No (Flag_Id) then
+
+ -- Generate:
+ -- Flag : Boolean := False;
+
+ Flag_Id := Make_Temporary (Loop_Loc, 'F');
+
+ Insert_Action (Loop_Stmt,
+ Make_Object_Declaration (Loop_Loc,
+ Defining_Identifier => Flag_Id,
+ Object_Definition =>
+ New_Reference_To (Standard_Boolean, Loop_Loc),
+ Expression =>
+ New_Reference_To (Standard_False, Loop_Loc)));
+
+ -- Prevent an unwanted optimization where the Current_Value of
+ -- the flag eliminates the if statement which stores the variant
+ -- values coming from the previous iteration.
+
+ -- Flag : Boolean := False;
+ -- loop
+ -- if Flag then -- condition rewritten to False
+ -- Old_N := Curr_N; -- and if statement eliminated
+ -- end if;
+ -- . . .
+ -- Flag := True;
+ -- end loop;
+
+ Set_Current_Value (Flag_Id, Empty);
+ end if;
+
+ -- Step 2: Create the temporaries which store the old and current
+ -- values of the associated expression.
+
+ -- Generate:
+ -- Curr : <type of Expr>;
+
+ Curr_Id := Make_Temporary (Loc, 'C');
+
+ Insert_Action (Loop_Stmt,
+ Make_Object_Declaration (Loop_Loc,
+ Defining_Identifier => Curr_Id,
+ Object_Definition =>
+ New_Reference_To (Etype (Expr), Loop_Loc)));
+
+ -- Generate:
+ -- Old : <type of Expr>;
+
+ Old_Id := Make_Temporary (Loc, 'P');
+
+ Insert_Action (Loop_Stmt,
+ Make_Object_Declaration (Loop_Loc,
+ Defining_Identifier => Old_Id,
+ Object_Definition =>
+ New_Reference_To (Etype (Expr), Loop_Loc)));
+
+ -- Restore original scope after all temporaries have been analyzed
+
+ Pop_Scope;
+
+ -- Step 3: Store value of the expression from the previous iteration
+
+ if No (Old_Assign) then
+ Old_Assign := New_List;
+ end if;
+
+ -- Generate:
+ -- Old := Curr;
+
+ Append_To (Old_Assign,
+ Make_Assignment_Statement (Loc,
+ Name => New_Reference_To (Old_Id, Loc),
+ Expression => New_Reference_To (Curr_Id, Loc)));
+
+ -- Step 4: Store the current value of the expression
+
+ if No (Curr_Assign) then
+ Curr_Assign := New_List;
+ end if;
+
+ -- Generate:
+ -- Curr := <Expr>;
+
+ Append_To (Curr_Assign,
+ Make_Assignment_Statement (Loc,
+ Name => New_Reference_To (Curr_Id, Loc),
+ Expression => Relocate_Node (Expr)));
+
+ -- Step 5: Create corresponding assertion to verify change of value
+
+ -- Generate:
+ -- pragma Assert (Curr <|> Old);
+
+ Prag :=
+ Make_Pragma (Loc,
+ Chars => Name_Assert,
+ Pragma_Argument_Associations => New_List (
+ Make_Pragma_Argument_Association (Loc,
+ Expression =>
+ Make_Op (Loc,
+ Curr_Val => New_Reference_To (Curr_Id, Loc),
+ Old_Val => New_Reference_To (Old_Id, Loc)))));
+
+ -- Generate:
+ -- if Curr /= Old then
+ -- <Prag>;
+
+ if No (If_Stmt) then
+
+ -- When there is just one termination variant, do not compare the
+ -- old and current value for equality, just check the pragma.
+
+ if Is_Last then
+ If_Stmt := Prag;
+ else
+ If_Stmt :=
+ Make_If_Statement (Loc,
+ Condition =>
+ Make_Op_Ne (Loc,
+ Left_Opnd => New_Reference_To (Curr_Id, Loc),
+ Right_Opnd => New_Reference_To (Old_Id, Loc)),
+ Then_Statements => New_List (Prag));
+ end if;
+
+ -- Generate:
+ -- else
+ -- <Prag>;
+ -- end if;
+
+ elsif Is_Last then
+ Set_Else_Statements (If_Stmt, New_List (Prag));
+
+ -- Generate:
+ -- elsif Curr /= Old then
+ -- <Prag>;
+
+ else
+ if Elsif_Parts (If_Stmt) = No_List then
+ Set_Elsif_Parts (If_Stmt, New_List);
+ end if;
+
+ Append_To (Elsif_Parts (If_Stmt),
+ Make_Elsif_Part (Loc,
+ Condition =>
+ Make_Op_Ne (Loc,
+ Left_Opnd => New_Reference_To (Curr_Id, Loc),
+ Right_Opnd => New_Reference_To (Old_Id, Loc)),
+ Then_Statements => New_List (Prag)));
+ end if;
+ end Process_Increase_Decrease;
+
+ -- Local variables
+
+ Arg : Node_Id;
+ Invar : Node_Id := Empty;
+
+ -- Start of processing for Expand_Pragma_Loop_Assertion
+
+ begin
+ -- Locate the enclosing loop for which this assertion applies. In the
+ -- case of Ada 2012 array iteration, we might be dealing with nested
+ -- loops. Only the outermost loop has an identifier.
+
+ Loop_Stmt := N;
+ while Present (Loop_Stmt) loop
+ if Nkind (Loop_Stmt) = N_Loop_Statement
+ and then Present (Identifier (Loop_Stmt))
+ then
+ exit;
+ end if;
+
+ Loop_Stmt := Parent (Loop_Stmt);
+ end loop;
+
+ Loop_Scop := Entity (Identifier (Loop_Stmt));
+
+ -- Process all pragma arguments
+
+ Arg := First (Pragma_Argument_Associations (N));
+ while Present (Arg) loop
+
+ -- Termination variants appear as components in an aggregate
+
+ if Chars (Arg) = Name_Variant then
+ declare
+ Variants : constant Node_Id := Expression (Arg);
+ Last_Var : constant Node_Id :=
+ Last (Component_Associations (Variants));
+ Variant : Node_Id;
+
+ begin
+ Variant := First (Component_Associations (Variants));
+ while Present (Variant) loop
+ Process_Increase_Decrease
+ (Variant => Variant,
+ Is_Last => Variant = Last_Var);
+
+ Next (Variant);
+ end loop;
+ end;
+
+ -- Invariant
+
+ else
+ Invar := Expression (Arg);
+ end if;
+
+ Next (Arg);
+ end loop;
+
+ -- Verify the invariant expression, generate:
+ -- pragma Assert (<Invar>);
+
+ -- Use the Sloc of the invariant for better error reporting
+
+ if Present (Invar) then
+ declare
+ Invar_Loc : constant Source_Ptr := Sloc (Invar);
+ begin
+ Insert_Action (N,
+ Make_Pragma (Invar_Loc,
+ Chars => Name_Assert,
+ Pragma_Argument_Associations => New_List (
+ Make_Pragma_Argument_Association (Invar_Loc,
+ Expression => Relocate_Node (Invar)))));
+ end;
+ end if;
+
+ -- Construct the segment which stores the old values of all expressions.
+ -- Generate:
+ -- if Flag then
+ -- <Old_Assign>
+ -- end if;
+
+ if Present (Old_Assign) then
+ Insert_Action (N,
+ Make_If_Statement (Loc,
+ Condition => New_Reference_To (Flag_Id, Loc),
+ Then_Statements => Old_Assign));
+ end if;
+
+ -- Update the values of all expressions
+
+ if Present (Curr_Assign) then
+ Insert_Actions (N, Curr_Assign);
+ end if;
+
+ -- Add the assertion circuitry to test all changes in expressions.
+ -- Generate:
+ -- if Flag then
+ -- <If_Stmt>
+ -- else
+ -- Flag := True;
+ -- end if;
+
+ if Present (If_Stmt) then
+ Insert_Action (N,
+ Make_If_Statement (Loc,
+ Condition => New_Reference_To (Flag_Id, Loc),
+ Then_Statements => New_List (If_Stmt),
+ Else_Statements => New_List (
+ Make_Assignment_Statement (Loc,
+ Name => New_Reference_To (Flag_Id, Loc),
+ Expression => New_Reference_To (Standard_True, Loc)))));
+ end if;
+
+ -- Note: the pragma has been completely transformed into a sequence of
+ -- corresponding declarations and statements. We leave it in the tree
+ -- for documentation purposes. It will be ignored by the backend.
+
+ end Expand_Pragma_Loop_Assertion;
+
--------------------------------
-- Expand_Pragma_Psect_Object --
--------------------------------
diff --git a/gcc/ada/exp_util.adb b/gcc/ada/exp_util.adb
index cc3213d03da..7c1ceeb8f7e 100644
--- a/gcc/ada/exp_util.adb
+++ b/gcc/ada/exp_util.adb
@@ -3840,11 +3840,11 @@ package body Exp_Util is
begin
if Suppress = All_Checks then
declare
- Svg : constant Suppress_Record := Scope_Suppress;
+ Sva : constant Suppress_Array := Scope_Suppress.Suppress;
begin
- Scope_Suppress := Suppress_All;
+ Scope_Suppress.Suppress := (others => True);
Insert_Actions (Assoc_Node, Ins_Actions);
- Scope_Suppress := Svg;
+ Scope_Suppress.Suppress := Sva;
end;
else
@@ -6727,7 +6727,7 @@ package body Exp_Util is
-- All this must not have any checks
- Scope_Suppress := Suppress_All;
+ Scope_Suppress.Suppress := (others => True);
-- If it is a scalar type and we need to capture the value, just make
-- a copy. Likewise for a function call, an attribute reference, an
diff --git a/gcc/ada/exp_vfpt.adb b/gcc/ada/exp_vfpt.adb
index 592114cf1d8..82d2fe16e7d 100644
--- a/gcc/ada/exp_vfpt.adb
+++ b/gcc/ada/exp_vfpt.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1997-2010, Free Software Foundation, Inc. --
+-- Copyright (C) 1997-2012, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -32,11 +32,87 @@ with Sem_Res; use Sem_Res;
with Sinfo; use Sinfo;
with Stand; use Stand;
with Tbuild; use Tbuild;
-with Uintp; use Uintp;
with Urealp; use Urealp;
+with Eval_Fat; use Eval_Fat;
package body Exp_VFpt is
+ -- Vax floating point format (from Vax Architecture Reference Manual
+ -- version 6):
+
+ -- Float F:
+ -- --------
+
+ -- 1 1
+ -- 5 4 7 6 0
+ -- +-+---------------+--------------+
+ -- |S| exp | fraction | A
+ -- +-+---------------+--------------+
+ -- | fraction | A + 2
+ -- +--------------------------------+
+
+ -- bit 15 is the sign bit,
+ -- bits 14:7 is the excess 128 binary exponent,
+ -- bits 6:0 and 31:16 the normalized 24-bit fraction with the redundant
+ -- most significant fraction bit not represented.
+
+ -- An exponent value of 0 together with a sign bit of 0, is taken to
+ -- indicate that the datum has a value of 0. Exponent values of 1 through
+ -- 255 indicate true binary exponents of -127 to +127. An exponent value
+ -- of 0, together with a sign bit of 1, is taken as reserved.
+
+ -- Note that fraction bits are not continuous in memory, VAX is little
+ -- endian (LSB first).
+
+ -- Float D:
+ -- --------
+
+ -- 1 1
+ -- 5 4 7 6 0
+ -- +-+---------------+--------------+
+ -- |S| exp | fraction | A
+ -- +-+---------------+--------------+
+ -- | fraction | A + 2
+ -- +--------------------------------+
+ -- | fraction | A + 4
+ -- +--------------------------------+
+ -- | fraction (low) | A + 6
+ -- +--------------------------------+
+
+ -- Note that the fraction bits are not continuous in memory. Bytes in a
+ -- words are stored in little endian format, but words are stored using
+ -- big endian format (PDP endian).
+
+ -- Like Float F but with 55 bits for the fraction.
+
+ -- Float G:
+ -- --------
+
+ -- 1 1
+ -- 5 4 4 3 0
+ -- +-+---------------------+--------+
+ -- |S| exp | fract | A
+ -- +-+---------------------+--------+
+ -- | fraction | A + 2
+ -- +--------------------------------+
+ -- | fraction | A + 4
+ -- +--------------------------------+
+ -- | fraction (low) | A + 6
+ -- +--------------------------------+
+
+ -- Exponent values of 1 through 2047 indicate true binary exponents of
+ -- -1023 to +1023.
+
+ -- Main differences compared to IEEE 754:
+
+ -- * No denormalized numbers
+ -- * No infinity
+ -- * No NaN
+ -- * No -0.0
+ -- * Reserved values (exp = 0, sign = 1)
+ -- * Vax mantissa represent values [0.5, 1)
+ -- * Bias is shifted by 1 (for single float: 128 on Vax, 127 on IEEE)
+
VAXFF_Digits : constant := 6;
VAXDF_Digits : constant := 9;
VAXGF_Digits : constant := 15;
@@ -481,93 +557,101 @@ package body Exp_VFpt is
Analyze_And_Resolve (N, Typ, Suppress => All_Checks);
end Expand_Vax_Foreign_Return;
- -----------------------------
- -- Expand_Vax_Real_Literal --
- -----------------------------
+ --------------------------------
+ -- Vax_Real_Literal_As_Signed --
+ --------------------------------
- procedure Expand_Vax_Real_Literal (N : Node_Id) is
- Loc : constant Source_Ptr := Sloc (N);
- Typ : constant Entity_Id := Etype (N);
- Btyp : constant Entity_Id := Base_Type (Typ);
- Stat : constant Boolean := Is_Static_Expression (N);
- Nod : Node_Id;
+ function Get_Vax_Real_Literal_As_Signed (N : Node_Id) return Uint is
+ Btyp : constant Entity_Id :=
+ Base_Type (Underlying_Type (Etype (N)));
+
+ Value : constant Ureal := Realval (N);
+ Negative : Boolean;
+ Fraction : UI;
+ Exponent : UI;
+ Res : UI;
+
+ Exponent_Size : Uint;
+ -- Number of bits for the exponent
- RE_Source : RE_Id;
- RE_Target : RE_Id;
- RE_Fncall : RE_Id;
- -- Entities for source, target and function call in conversion
+ Fraction_Size : Uint;
+ -- Number of bits for the fraction
+ Uintp_Mark : constant Uintp.Save_Mark := Mark;
+ -- Use the mark & release feature to delete temporaries
begin
- -- We do not know how to convert Vax format real literals, so what
- -- we do is to convert these to be IEEE literals, and introduce the
- -- necessary conversion operation.
+ -- Extract the sign now
- if Vax_Float (Btyp) then
- -- What we want to construct here is
+ Negative := UR_Is_Negative (Value);
- -- x!(y_to_z (1.0E0))
+ -- Decompose the number
- -- where
+ Decompose_Int (Btyp, abs Value, Fraction, Exponent, Round_Even);
- -- x is the base type of the literal (Btyp)
+ -- Number of bits for the fraction, leading fraction bit is implicit
- -- y_to_z is
+ Fraction_Size := Machine_Mantissa_Value (Btyp) - Int'(1);
- -- s_to_f for F_Float
- -- t_to_g for G_Float
- -- t_to_d for D_Float
+ -- Number of bits for the exponent (one bit for the sign)
- -- The literal is typed as S (for F_Float) or T otherwise
+ Exponent_Size := RM_Size (Btyp) - Fraction_Size - Int'(1);
- -- We do all our own construction, analysis, and expansion here,
- -- since things are at too low a level to use Analyze or Expand
- -- to get this built (we get circularities and other strange
- -- problems if we try!)
+ if Fraction = Uint_0 then
+ -- Handle zero
- if Digits_Value (Btyp) = VAXFF_Digits then
- RE_Source := RE_S;
- RE_Target := RE_F;
- RE_Fncall := RE_S_To_F;
+ Res := Uint_0;
- elsif Digits_Value (Btyp) = VAXDF_Digits then
- RE_Source := RE_T;
- RE_Target := RE_D;
- RE_Fncall := RE_T_To_D;
+ elsif Exponent <= -(Uint_2 ** (Exponent_Size - 1)) then
+ -- Underflow
- else pragma Assert (Digits_Value (Btyp) = VAXGF_Digits);
- RE_Source := RE_T;
- RE_Target := RE_G;
- RE_Fncall := RE_T_To_G;
- end if;
+ Res := Uint_0;
+ else
+ -- Check for overflow
- Nod := Relocate_Node (N);
+ pragma Assert (Exponent < Uint_2 ** (Exponent_Size - 1));
- Set_Etype (Nod, RTE (RE_Source));
- Set_Analyzed (Nod, True);
+ -- MSB of the fraction must be 1
- Nod :=
- Make_Function_Call (Loc,
- Name => New_Occurrence_Of (RTE (RE_Fncall), Loc),
- Parameter_Associations => New_List (Nod));
+ pragma Assert (Fraction / Uint_2 ** Fraction_Size = Uint_1);
- Set_Etype (Nod, RTE (RE_Target));
- Set_Analyzed (Nod, True);
+ -- Remove the redudant most significant fraction bit
- Nod :=
- Make_Unchecked_Type_Conversion (Loc,
- Subtype_Mark => New_Occurrence_Of (Typ, Loc),
- Expression => Nod);
+ Fraction := Fraction - Uint_2 ** Fraction_Size;
- Set_Etype (Nod, Typ);
- Set_Analyzed (Nod, True);
- Rewrite (N, Nod);
+ -- Build the fraction part. Note that this field is in mixed
+ -- endianness: words are stored using little endianness, while bytes
+ -- in words are stored using big endianness.
- -- This odd expression is still a static expression. Note that
- -- the routine Sem_Eval.Expr_Value_R understands this.
+ Res := Uint_0;
+ for I in 1 .. UI_To_Int (RM_Size (Btyp)) / 16 loop
+ Res := (Res * (Uint_2 ** 16)) + (Fraction mod (Uint_2 ** 16));
+ Fraction := Fraction / (Uint_2 ** 16);
+ end loop;
- Set_Is_Static_Expression (N, Stat);
+ -- The sign bit
+
+ if Negative then
+ Res := Res + Int (2**15);
+ end if;
+
+ -- The exponent
+
+ Res := Res + (Exponent + Uint_2 ** (Exponent_Size - 1))
+ * Uint_2 ** (15 - Exponent_Size);
+
+ -- Until now, we have created an unsigned number, but an underlying
+ -- type is a signed type. Convert to a signed number to avoid
+ -- overflow in gigi.
+
+ if Res >= Uint_2 ** (Exponent_Size + Fraction_Size) then
+ Res := Res - Uint_2 ** (Exponent_Size + Fraction_Size + 1);
+ end if;
end if;
- end Expand_Vax_Real_Literal;
+
+ Release_And_Save (Uintp_Mark, Res);
+
+ return Res;
+ end Get_Vax_Real_Literal_As_Signed;
----------------------
-- Expand_Vax_Valid --
diff --git a/gcc/ada/exp_vfpt.ads b/gcc/ada/exp_vfpt.ads
index fdca701cfb1..db018669435 100644
--- a/gcc/ada/exp_vfpt.ads
+++ b/gcc/ada/exp_vfpt.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 1992-2008, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -28,6 +28,7 @@
-- point formats as used on the Vax and the Alpha and the ia64.
with Types; use Types;
+with Uintp; use Uintp;
package Exp_VFpt is
@@ -51,10 +52,12 @@ package Exp_VFpt is
-- that moves the return value to an integer location on Alpha/VMS,
-- noop everywhere else.
- procedure Expand_Vax_Real_Literal (N : Node_Id);
- -- The node N is a real literal node where the type is a Vax floating-point
- -- type. This procedure rewrites the node to eliminate the occurrence of
- -- such constants.
+ function Get_Vax_Real_Literal_As_Signed (N : Node_Id) return Uint;
+ -- Get the Vax binary representation of a real literal whose type is a Vax
+ -- floating-point type. This is used by gigi. Previously we expanded real
+ -- literal to a call to a LIB$OTS routine that performed the conversion.
+ -- This worked correctly from a funcional point of view, but was
+ -- inefficient and generated huge functions for aggregate initializations.
procedure Expand_Vax_Valid (N : Node_Id);
-- The node N is an attribute reference node for the Valid attribute where
diff --git a/gcc/ada/expander.adb b/gcc/ada/expander.adb
index af367d9512d..83a692067cf 100644
--- a/gcc/ada/expander.adb
+++ b/gcc/ada/expander.adb
@@ -25,7 +25,6 @@
with Atree; use Atree;
with Debug_A; use Debug_A;
-with Errout; use Errout;
with Exp_Aggr; use Exp_Aggr;
with Exp_Alfa; use Exp_Alfa;
with Exp_Attr; use Exp_Attr;
diff --git a/gcc/ada/fe.h b/gcc/ada/fe.h
index 9f5d64f01fe..fe52233202b 100644
--- a/gcc/ada/fe.h
+++ b/gcc/ada/fe.h
@@ -80,6 +80,10 @@ extern Boolean Is_Entity_Name (Node_Id);
#define Get_Attribute_Definition_Clause einfo__get_attribute_definition_clause
extern Node_Id Get_Attribute_Definition_Clause (Entity_Id, char);
+/* atree: */
+
+#define Serious_Errors_Detected atree__serious_errors_detected
+
/* errout: */
#define Error_Msg_N errout__error_msg_n
@@ -95,7 +99,6 @@ extern void Set_Identifier_Casing (Char *, const Char *);
#define Error_Msg_Node_2 err_vars__error_msg_node_2
#define Error_Msg_Uint_1 err_vars__error_msg_uint_1
#define Error_Msg_Uint_2 err_vars__error_msg_uint_2
-#define Serious_Errors_Detected err_vars__serious_errors_detected
extern Entity_Id Error_Msg_Node_2;
extern Uint Error_Msg_Uint_1;
@@ -156,6 +159,11 @@ extern void Get_External_Name_With_Suffix (Entity_Id, Fat_Pointer);
extern Boolean Is_Fully_Repped_Tagged_Type (Entity_Id);
+/* exp_vfpt: */
+
+#define Get_Vax_Real_Literal_As_Signed exp_vfpt__get_vax_real_literal_as_signed
+extern Ureal Get_Vax_Real_Literal_As_Signed (Node_Id);
+
/* lib: */
#define Cunit lib__cunit
diff --git a/gcc/ada/fmap.adb b/gcc/ada/fmap.adb
index 171f7a18e7d..f5432096e28 100644
--- a/gcc/ada/fmap.adb
+++ b/gcc/ada/fmap.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2001-2010, Free Software Foundation, Inc. --
+-- Copyright (C) 2001-2012, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
diff --git a/gcc/ada/fmap.ads b/gcc/ada/fmap.ads
index f1d54db4733..19aa0693ef5 100644
--- a/gcc/ada/fmap.ads
+++ b/gcc/ada/fmap.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 2001-2009, Free Software Foundation, Inc. --
+-- Copyright (C) 2001-2012, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
diff --git a/gcc/ada/gcc-interface/Make-lang.in b/gcc/ada/gcc-interface/Make-lang.in
index 05b3b2be8d9..7f9e38a3710 100644
--- a/gcc/ada/gcc-interface/Make-lang.in
+++ b/gcc/ada/gcc-interface/Make-lang.in
@@ -122,7 +122,7 @@ ifeq ($(build), $(host))
# put the host RTS dir first in the PATH to hide the default runtime
# files that are among the sources
- RTS_DIR=$(strip $(subst \,/,$(shell gnatls -v | grep adalib )))
+ RTS_DIR:=$(strip $(subst \,/,$(shell gnatls -v | grep adalib )))
ADA_TOOLS_FLAGS_TO_PASS=\
CC="$(CC)" \
@@ -157,7 +157,7 @@ else
else
# This is a canadian cross. We should use a toolchain running on the
# build platform and targeting the host platform.
- RTS_DIR=$(strip $(subst \,/,$(shell $(GNATLS_FOR_HOST) -v | grep adalib )))
+ RTS_DIR:=$(strip $(subst \,/,$(shell $(GNATLS_FOR_HOST) -v | grep adalib )))
ADA_TOOLS_FLAGS_TO_PASS=\
CC="$(CC)" \
$(COMMON_FLAGS_TO_PASS) $(ADA_FLAGS_TO_PASS) \
@@ -574,7 +574,7 @@ canadian-gnattools: force
$(MAKE) -C ada $(ADA_TOOLS_FLAGS_TO_PASS) gnattools2
$(MAKE) -C ada $(ADA_TOOLS_FLAGS_TO_PASS) gnattools4
-gnatlib gnatlib-sjlj gnatlib-zcx gnatlib-shared: force
+gnatlib gnatlib-sjlj gnatlib-zcx gnatlib-shared: ada/s-oscons.ads force
$(MAKE) -C ada $(COMMON_FLAGS_TO_PASS) \
GNATLIBFLAGS="$(GNATLIBFLAGS)" \
GNATLIBCFLAGS="$(GNATLIBCFLAGS)" \
@@ -1115,9 +1115,10 @@ ada/alloc.o : ada/alloc.ads ada/system.ads
ada/aspects.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/aspects.adb \
ada/atree.ads ada/atree.adb ada/casing.ads ada/debug.ads ada/einfo.ads \
- ada/einfo.adb ada/gnat.ads ada/g-htable.ads ada/hostparm.ads \
- ada/namet.ads ada/nlists.ads ada/nlists.adb ada/opt.ads ada/output.ads \
- ada/sinfo.ads ada/sinfo.adb ada/sinput.ads ada/snames.ads ada/stand.ads \
+ ada/einfo.adb ada/err_vars.ads ada/errout.ads ada/erroutc.ads \
+ ada/gnat.ads ada/g-htable.ads ada/hostparm.ads ada/namet.ads \
+ ada/nlists.ads ada/nlists.adb ada/opt.ads ada/output.ads ada/sinfo.ads \
+ ada/sinfo.adb ada/sinput.ads ada/snames.ads ada/stand.ads \
ada/system.ads ada/s-exctab.ads ada/s-htable.ads ada/s-htable.adb \
ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads \
ada/s-stalib.ads ada/s-strhas.ads ada/s-string.ads ada/s-traent.ads \
@@ -1340,15 +1341,16 @@ ada/debug_a.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/einfo.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \
ada/atree.adb ada/casing.ads ada/debug.ads ada/einfo.ads ada/einfo.adb \
- ada/gnat.ads ada/g-htable.ads ada/hostparm.ads ada/namet.ads \
- ada/nlists.ads ada/nlists.adb ada/opt.ads ada/output.ads ada/sinfo.ads \
- ada/sinfo.adb ada/sinput.ads ada/snames.ads ada/snames.adb \
- ada/stand.ads ada/system.ads ada/s-exctab.ads ada/s-htable.ads \
- ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads \
- ada/s-stalib.ads ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads \
- ada/s-wchcon.ads ada/table.ads ada/table.adb ada/tree_io.ads \
- ada/types.ads ada/uintp.ads ada/uintp.adb ada/unchconv.ads \
- ada/unchdeal.ads ada/urealp.ads ada/urealp.adb
+ ada/err_vars.ads ada/errout.ads ada/erroutc.ads ada/gnat.ads \
+ ada/g-htable.ads ada/hostparm.ads ada/namet.ads ada/nlists.ads \
+ ada/nlists.adb ada/opt.ads ada/output.ads ada/sinfo.ads ada/sinfo.adb \
+ ada/sinput.ads ada/snames.ads ada/snames.adb ada/stand.ads \
+ ada/system.ads ada/s-exctab.ads ada/s-htable.ads ada/s-imenne.ads \
+ ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads ada/s-stalib.ads \
+ ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads \
+ ada/table.ads ada/table.adb ada/tree_io.ads ada/types.ads ada/uintp.ads \
+ ada/uintp.adb ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads \
+ ada/urealp.adb
ada/elists.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/alloc.ads ada/debug.ads ada/elists.ads \
@@ -1406,12 +1408,12 @@ ada/erroutc.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/eval_fat.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/alloc.ads ada/debug.ads ada/einfo.ads \
ada/err_vars.ads ada/errout.ads ada/erroutc.ads ada/eval_fat.ads \
- ada/eval_fat.adb ada/gnat.ads ada/g-htable.ads ada/hostparm.ads \
- ada/namet.ads ada/opt.ads ada/output.ads ada/rident.ads ada/snames.ads \
- ada/system.ads ada/s-exctab.ads ada/s-htable.ads ada/s-memory.ads \
- ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads ada/s-stalib.ads \
- ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads \
- ada/table.ads ada/table.adb ada/targparm.ads ada/tree_io.ads \
+ ada/eval_fat.adb ada/exp_tss.ads ada/gnat.ads ada/g-htable.ads \
+ ada/hostparm.ads ada/namet.ads ada/opt.ads ada/output.ads \
+ ada/sem_util.ads ada/snames.ads ada/system.ads ada/s-exctab.ads \
+ ada/s-htable.ads ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads \
+ ada/s-stalib.ads ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads \
+ ada/s-wchcon.ads ada/table.ads ada/table.adb ada/tree_io.ads \
ada/types.ads ada/uintp.ads ada/uintp.adb ada/unchconv.ads \
ada/unchdeal.ads ada/urealp.ads ada/urealp.adb
@@ -1452,18 +1454,19 @@ ada/exp_aggr.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/exp_alfa.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \
ada/atree.adb ada/casing.ads ada/debug.ads ada/einfo.ads ada/einfo.adb \
- ada/exp_alfa.ads ada/exp_alfa.adb ada/exp_attr.ads ada/exp_ch4.ads \
- ada/exp_ch6.ads ada/exp_dbug.ads ada/exp_tss.ads ada/exp_util.ads \
- ada/hostparm.ads ada/namet.ads ada/nlists.ads ada/nlists.adb \
- ada/opt.ads ada/output.ads ada/rtsfind.ads ada/sem_aux.ads \
- ada/sem_aux.adb ada/sem_res.ads ada/sem_util.ads ada/sinfo.ads \
- ada/sinfo.adb ada/sinput.ads ada/snames.ads ada/stand.ads \
- ada/system.ads ada/s-exctab.ads ada/s-imenne.ads ada/s-memory.ads \
- ada/s-os_lib.ads ada/s-parame.ads ada/s-soflin.ads ada/s-stache.ads \
- ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads \
- ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads \
- ada/table.adb ada/tbuild.ads ada/tree_io.ads ada/types.ads \
- ada/uintp.ads ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads
+ ada/err_vars.ads ada/errout.ads ada/erroutc.ads ada/exp_alfa.ads \
+ ada/exp_alfa.adb ada/exp_attr.ads ada/exp_ch4.ads ada/exp_ch6.ads \
+ ada/exp_dbug.ads ada/exp_tss.ads ada/exp_util.ads ada/hostparm.ads \
+ ada/namet.ads ada/nlists.ads ada/nlists.adb ada/opt.ads ada/output.ads \
+ ada/rtsfind.ads ada/sem_aux.ads ada/sem_aux.adb ada/sem_res.ads \
+ ada/sem_util.ads ada/sinfo.ads ada/sinfo.adb ada/sinput.ads \
+ ada/snames.ads ada/stand.ads ada/system.ads ada/s-exctab.ads \
+ ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads \
+ ada/s-soflin.ads ada/s-stache.ads ada/s-stalib.ads ada/s-stoele.ads \
+ ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads \
+ ada/s-wchcon.ads ada/table.ads ada/table.adb ada/tbuild.ads \
+ ada/tree_io.ads ada/types.ads ada/uintp.ads ada/unchconv.ads \
+ ada/unchdeal.ads ada/urealp.ads
ada/exp_atag.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \
@@ -1526,19 +1529,19 @@ ada/exp_attr.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/exp_cg.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \
ada/atree.adb ada/casing.ads ada/debug.ads ada/einfo.ads ada/einfo.adb \
- ada/elists.ads ada/elists.adb ada/exp_cg.ads ada/exp_cg.adb \
- ada/exp_dbug.ads ada/exp_disp.ads ada/exp_tss.ads ada/gnat.ads \
- ada/g-htable.ads ada/hostparm.ads ada/lib.ads ada/namet.ads \
- ada/nlists.ads ada/opt.ads ada/output.ads ada/sem_aux.ads \
- ada/sem_aux.adb ada/sem_disp.ads ada/sem_type.ads ada/sem_util.ads \
- ada/sinfo.ads ada/sinfo.adb ada/sinput.ads ada/snames.ads ada/stand.ads \
- ada/system.ads ada/s-exctab.ads ada/s-htable.ads ada/s-imenne.ads \
- ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads ada/s-secsta.ads \
- ada/s-soflin.ads ada/s-stache.ads ada/s-stalib.ads ada/s-stoele.ads \
- ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads \
- ada/s-wchcon.ads ada/table.ads ada/table.adb ada/tree_io.ads \
- ada/types.ads ada/uintp.ads ada/uintp.adb ada/unchconv.ads \
- ada/unchdeal.ads ada/urealp.ads
+ ada/elists.ads ada/elists.adb ada/err_vars.ads ada/errout.ads \
+ ada/erroutc.ads ada/exp_cg.ads ada/exp_cg.adb ada/exp_dbug.ads \
+ ada/exp_disp.ads ada/exp_tss.ads ada/gnat.ads ada/g-htable.ads \
+ ada/hostparm.ads ada/lib.ads ada/namet.ads ada/nlists.ads ada/opt.ads \
+ ada/output.ads ada/sem_aux.ads ada/sem_aux.adb ada/sem_disp.ads \
+ ada/sem_type.ads ada/sem_util.ads ada/sinfo.ads ada/sinfo.adb \
+ ada/sinput.ads ada/snames.ads ada/stand.ads ada/system.ads \
+ ada/s-exctab.ads ada/s-htable.ads ada/s-imenne.ads ada/s-memory.ads \
+ ada/s-os_lib.ads ada/s-parame.ads ada/s-secsta.ads ada/s-soflin.ads \
+ ada/s-stache.ads ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb \
+ ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads \
+ ada/table.ads ada/table.adb ada/tree_io.ads ada/types.ads ada/uintp.ads \
+ ada/uintp.adb ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads
ada/exp_ch11.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \
@@ -1569,18 +1572,18 @@ ada/exp_ch11.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/exp_ch12.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \
ada/atree.adb ada/casing.ads ada/checks.ads ada/debug.ads ada/einfo.ads \
- ada/einfo.adb ada/elists.ads ada/exp_ch12.ads ada/exp_ch12.adb \
- ada/exp_tss.ads ada/exp_util.ads ada/hostparm.ads ada/lib.ads \
- ada/namet.ads ada/nlists.ads ada/nmake.ads ada/nmake.adb ada/opt.ads \
- ada/output.ads ada/restrict.ads ada/rident.ads ada/rtsfind.ads \
- ada/sem_aux.ads ada/sinfo.ads ada/sinfo.adb ada/sinput.ads \
- ada/snames.ads ada/stand.ads ada/stringt.ads ada/system.ads \
- ada/s-exctab.ads ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads \
- ada/s-parame.ads ada/s-rident.ads ada/s-stalib.ads ada/s-string.ads \
- ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads \
- ada/table.adb ada/tbuild.ads ada/tbuild.adb ada/tree_io.ads \
- ada/types.ads ada/uintp.ads ada/unchconv.ads ada/unchdeal.ads \
- ada/urealp.ads
+ ada/einfo.adb ada/elists.ads ada/err_vars.ads ada/errout.ads \
+ ada/erroutc.ads ada/exp_ch12.ads ada/exp_ch12.adb ada/exp_tss.ads \
+ ada/exp_util.ads ada/hostparm.ads ada/lib.ads ada/namet.ads \
+ ada/nlists.ads ada/nmake.ads ada/nmake.adb ada/opt.ads ada/output.ads \
+ ada/restrict.ads ada/rident.ads ada/rtsfind.ads ada/sem_aux.ads \
+ ada/sinfo.ads ada/sinfo.adb ada/sinput.ads ada/snames.ads ada/stand.ads \
+ ada/stringt.ads ada/system.ads ada/s-exctab.ads ada/s-imenne.ads \
+ ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads \
+ ada/s-stalib.ads ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads \
+ ada/s-wchcon.ads ada/table.ads ada/table.adb ada/tbuild.ads \
+ ada/tbuild.adb ada/tree_io.ads ada/types.ads ada/uintp.ads \
+ ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads
ada/exp_ch13.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \
@@ -1608,11 +1611,11 @@ ada/exp_ch2.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/atree.adb ada/casing.ads ada/checks.ads ada/debug.ads ada/einfo.ads \
ada/einfo.adb ada/elists.ads ada/elists.adb ada/err_vars.ads \
ada/errout.ads ada/erroutc.ads ada/exp_ch2.ads ada/exp_ch2.adb \
- ada/exp_smem.ads ada/exp_tss.ads ada/exp_util.ads ada/exp_vfpt.ads \
- ada/hostparm.ads ada/namet.ads ada/nlists.ads ada/nmake.ads \
- ada/nmake.adb ada/opt.ads ada/output.ads ada/rtsfind.ads ada/sem.ads \
- ada/sem_eval.ads ada/sem_res.ads ada/sem_util.ads ada/sem_warn.ads \
- ada/sinfo.ads ada/sinfo.adb ada/sinput.ads ada/snames.ads ada/stand.ads \
+ ada/exp_smem.ads ada/exp_tss.ads ada/exp_util.ads ada/hostparm.ads \
+ ada/namet.ads ada/nlists.ads ada/nmake.ads ada/nmake.adb ada/opt.ads \
+ ada/output.ads ada/rtsfind.ads ada/sem.ads ada/sem_eval.ads \
+ ada/sem_res.ads ada/sem_util.ads ada/sem_warn.ads ada/sinfo.ads \
+ ada/sinfo.adb ada/sinput.ads ada/snames.ads ada/stand.ads \
ada/system.ads ada/s-exctab.ads ada/s-imenne.ads ada/s-memory.ads \
ada/s-os_lib.ads ada/s-parame.ads ada/s-stalib.ads ada/s-string.ads \
ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads \
@@ -1691,16 +1694,16 @@ ada/exp_ch5.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \
ada/atree.adb ada/casing.ads ada/checks.ads ada/checks.adb \
ada/csets.ads ada/debug.ads ada/einfo.ads ada/einfo.adb ada/elists.ads \
- ada/err_vars.ads ada/errout.ads ada/erroutc.ads ada/eval_fat.ads \
- ada/exp_aggr.ads ada/exp_ch11.ads ada/exp_ch2.ads ada/exp_ch4.ads \
- ada/exp_ch5.ads ada/exp_ch5.adb ada/exp_ch6.ads ada/exp_ch7.ads \
- ada/exp_dbug.ads ada/exp_disp.ads ada/exp_pakd.ads ada/exp_tss.ads \
- ada/exp_util.ads ada/exp_util.adb ada/expander.ads ada/fname.ads \
- ada/fname-uf.ads ada/freeze.ads ada/get_targ.ads ada/gnat.ads \
- ada/g-htable.ads ada/hostparm.ads ada/inline.ads ada/itypes.ads \
- ada/lib.ads ada/lib-util.ads ada/lib-xref.ads ada/namet.ads \
- ada/namet-sp.ads ada/nlists.ads ada/nlists.adb ada/nmake.ads \
- ada/nmake.adb ada/opt.ads ada/output.ads ada/put_alfa.ads \
+ ada/elists.adb ada/err_vars.ads ada/errout.ads ada/erroutc.ads \
+ ada/eval_fat.ads ada/exp_aggr.ads ada/exp_ch11.ads ada/exp_ch2.ads \
+ ada/exp_ch4.ads ada/exp_ch5.ads ada/exp_ch5.adb ada/exp_ch6.ads \
+ ada/exp_ch7.ads ada/exp_dbug.ads ada/exp_disp.ads ada/exp_pakd.ads \
+ ada/exp_tss.ads ada/exp_util.ads ada/exp_util.adb ada/expander.ads \
+ ada/fname.ads ada/fname-uf.ads ada/freeze.ads ada/get_targ.ads \
+ ada/gnat.ads ada/g-htable.ads ada/hostparm.ads ada/inline.ads \
+ ada/itypes.ads ada/lib.ads ada/lib-util.ads ada/lib-xref.ads \
+ ada/namet.ads ada/namet-sp.ads ada/nlists.ads ada/nlists.adb \
+ ada/nmake.ads ada/nmake.adb ada/opt.ads ada/output.ads ada/put_alfa.ads \
ada/restrict.ads ada/restrict.adb ada/rident.ads ada/rtsfind.ads \
ada/scans.ads ada/sem.ads ada/sem_attr.ads ada/sem_aux.ads \
ada/sem_cat.ads ada/sem_ch13.ads ada/sem_ch3.ads ada/sem_ch6.ads \
@@ -1880,20 +1883,21 @@ ada/exp_code.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/exp_dbug.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \
ada/atree.adb ada/casing.ads ada/debug.ads ada/einfo.ads ada/einfo.adb \
- ada/exp_dbug.ads ada/exp_dbug.adb ada/exp_tss.ads ada/gnat.ads \
- ada/g-htable.ads ada/hostparm.ads ada/interfac.ads ada/namet.ads \
- ada/namet.adb ada/nlists.ads ada/nlists.adb ada/nmake.ads ada/nmake.adb \
- ada/opt.ads ada/output.ads ada/rident.ads ada/sem_aux.ads \
- ada/sem_eval.ads ada/sem_util.ads ada/sinfo.ads ada/sinfo.adb \
- ada/sinput.ads ada/snames.ads ada/stand.ads ada/stringt.ads \
- ada/system.ads ada/s-exctab.ads ada/s-htable.ads ada/s-imenne.ads \
- ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads \
- ada/s-secsta.ads ada/s-soflin.ads ada/s-stache.ads ada/s-stalib.ads \
- ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads \
- ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads ada/table.adb \
- ada/targparm.ads ada/tbuild.ads ada/tree_io.ads ada/types.ads \
- ada/uintp.ads ada/uintp.adb ada/unchconv.ads ada/unchdeal.ads \
- ada/urealp.ads ada/urealp.adb ada/widechar.ads
+ ada/err_vars.ads ada/errout.ads ada/erroutc.ads ada/exp_dbug.ads \
+ ada/exp_dbug.adb ada/exp_tss.ads ada/gnat.ads ada/g-htable.ads \
+ ada/hostparm.ads ada/interfac.ads ada/namet.ads ada/namet.adb \
+ ada/nlists.ads ada/nlists.adb ada/nmake.ads ada/nmake.adb ada/opt.ads \
+ ada/output.ads ada/rident.ads ada/sem_aux.ads ada/sem_eval.ads \
+ ada/sem_util.ads ada/sinfo.ads ada/sinfo.adb ada/sinput.ads \
+ ada/snames.ads ada/stand.ads ada/stringt.ads ada/system.ads \
+ ada/s-exctab.ads ada/s-htable.ads ada/s-imenne.ads ada/s-memory.ads \
+ ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads ada/s-secsta.ads \
+ ada/s-soflin.ads ada/s-stache.ads ada/s-stalib.ads ada/s-stoele.ads \
+ ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads \
+ ada/s-wchcon.ads ada/table.ads ada/table.adb ada/targparm.ads \
+ ada/tbuild.ads ada/tree_io.ads ada/types.ads ada/uintp.ads \
+ ada/uintp.adb ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads \
+ ada/urealp.adb ada/widechar.ads
ada/exp_disp.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \
@@ -2063,40 +2067,42 @@ ada/exp_prag.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/hostparm.ads ada/lib.ads ada/namet.ads ada/nlists.ads \
ada/nlists.adb ada/nmake.ads ada/nmake.adb ada/opt.ads ada/output.ads \
ada/restrict.ads ada/restrict.adb ada/rident.ads ada/rtsfind.ads \
- ada/scans.ads ada/sem.ads ada/sem_res.ads ada/sem_util.ads \
- ada/sinfo.ads ada/sinfo.adb ada/sinput.ads ada/sinput.adb \
- ada/snames.ads ada/snames.adb ada/stand.ads ada/stringt.ads \
- ada/stringt.adb ada/system.ads ada/s-exctab.ads ada/s-htable.ads \
- ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads \
- ada/s-rident.ads ada/s-secsta.ads ada/s-soflin.ads ada/s-stache.ads \
- ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads \
- ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads \
- ada/table.adb ada/targparm.ads ada/tbuild.ads ada/tree_io.ads \
- ada/types.ads ada/uintp.ads ada/uintp.adb ada/uname.ads \
+ ada/scans.ads ada/sem.ads ada/sem_ch8.ads ada/sem_res.ads \
+ ada/sem_util.ads ada/sinfo.ads ada/sinfo.adb ada/sinput.ads \
+ ada/sinput.adb ada/snames.ads ada/snames.adb ada/stand.ads \
+ ada/stringt.ads ada/stringt.adb ada/system.ads ada/s-exctab.ads \
+ ada/s-htable.ads ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads \
+ ada/s-parame.ads ada/s-rident.ads ada/s-secsta.ads ada/s-soflin.ads \
+ ada/s-stache.ads ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb \
+ ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads \
+ ada/table.ads ada/table.adb ada/targparm.ads ada/tbuild.ads \
+ ada/tree_io.ads ada/types.ads ada/uintp.ads ada/uintp.adb ada/uname.ads \
ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/widechar.ads
ada/exp_sel.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/alloc.ads ada/atree.ads ada/debug.ads \
- ada/einfo.ads ada/einfo.adb ada/elists.ads ada/exp_sel.ads \
- ada/exp_sel.adb ada/hostparm.ads ada/lib.ads ada/namet.ads \
- ada/nlists.ads ada/nlists.adb ada/nmake.ads ada/nmake.adb ada/opt.ads \
- ada/output.ads ada/restrict.ads ada/rident.ads ada/rtsfind.ads \
- ada/sem_aux.ads ada/sinfo.ads ada/sinfo.adb ada/snames.ads \
- ada/stand.ads ada/stringt.ads ada/system.ads ada/s-exctab.ads \
- ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads \
- ada/s-rident.ads ada/s-stalib.ads ada/s-string.ads ada/s-traent.ads \
- ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads ada/table.adb \
- ada/tbuild.ads ada/tbuild.adb ada/tree_io.ads ada/types.ads \
- ada/uintp.ads ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads
+ ada/einfo.ads ada/einfo.adb ada/elists.ads ada/err_vars.ads \
+ ada/errout.ads ada/erroutc.ads ada/exp_sel.ads ada/exp_sel.adb \
+ ada/hostparm.ads ada/lib.ads ada/namet.ads ada/nlists.ads \
+ ada/nlists.adb ada/nmake.ads ada/nmake.adb ada/opt.ads ada/output.ads \
+ ada/restrict.ads ada/rident.ads ada/rtsfind.ads ada/sem_aux.ads \
+ ada/sinfo.ads ada/sinfo.adb ada/snames.ads ada/stand.ads \
+ ada/stringt.ads ada/system.ads ada/s-exctab.ads ada/s-imenne.ads \
+ ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads \
+ ada/s-stalib.ads ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads \
+ ada/s-wchcon.ads ada/table.ads ada/table.adb ada/tbuild.ads \
+ ada/tbuild.adb ada/tree_io.ads ada/types.ads ada/uintp.ads \
+ ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads
ada/exp_smem.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \
ada/atree.adb ada/casing.ads ada/debug.ads ada/einfo.ads ada/einfo.adb \
- ada/exp_ch9.ads ada/exp_smem.ads ada/exp_smem.adb ada/exp_tss.ads \
- ada/exp_util.ads ada/hostparm.ads ada/namet.ads ada/nlists.ads \
- ada/nlists.adb ada/nmake.ads ada/nmake.adb ada/opt.ads ada/output.ads \
- ada/rtsfind.ads ada/sem.ads ada/sem_aux.ads ada/sem_util.ads \
- ada/sinfo.ads ada/sinfo.adb ada/sinput.ads ada/snames.ads ada/stand.ads \
+ ada/err_vars.ads ada/errout.ads ada/erroutc.ads ada/exp_ch9.ads \
+ ada/exp_smem.ads ada/exp_smem.adb ada/exp_tss.ads ada/exp_util.ads \
+ ada/hostparm.ads ada/namet.ads ada/nlists.ads ada/nlists.adb \
+ ada/nmake.ads ada/nmake.adb ada/opt.ads ada/output.ads ada/rtsfind.ads \
+ ada/sem.ads ada/sem_aux.ads ada/sem_util.ads ada/sinfo.ads \
+ ada/sinfo.adb ada/sinput.ads ada/snames.ads ada/stand.ads \
ada/stringt.ads ada/stringt.adb ada/system.ads ada/s-exctab.ads \
ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads \
ada/s-stalib.ads ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads \
@@ -2107,20 +2113,20 @@ ada/exp_smem.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/exp_strm.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \
ada/atree.adb ada/casing.ads ada/debug.ads ada/einfo.ads ada/einfo.adb \
- ada/elists.ads ada/elists.adb ada/exp_strm.ads ada/exp_strm.adb \
- ada/exp_tss.ads ada/exp_util.ads ada/get_targ.ads ada/gnat.ads \
- ada/g-htable.ads ada/hostparm.ads ada/lib.ads ada/namet.ads \
- ada/nlists.ads ada/nlists.adb ada/nmake.ads ada/nmake.adb ada/opt.ads \
- ada/output.ads ada/restrict.ads ada/rident.ads ada/rtsfind.ads \
- ada/sem_aux.ads ada/sem_util.ads ada/sinfo.ads ada/sinfo.adb \
- ada/sinput.ads ada/snames.ads ada/stand.ads ada/stringt.ads \
- ada/system.ads ada/s-exctab.ads ada/s-htable.ads ada/s-imenne.ads \
- ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads \
- ada/s-stalib.ads ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads \
- ada/s-wchcon.ads ada/table.ads ada/table.adb ada/tbuild.ads \
- ada/tbuild.adb ada/tree_io.ads ada/ttypes.ads ada/types.ads \
- ada/uintp.ads ada/uintp.adb ada/unchconv.ads ada/unchdeal.ads \
- ada/urealp.ads
+ ada/elists.ads ada/elists.adb ada/err_vars.ads ada/errout.ads \
+ ada/erroutc.ads ada/exp_strm.ads ada/exp_strm.adb ada/exp_tss.ads \
+ ada/exp_util.ads ada/get_targ.ads ada/gnat.ads ada/g-htable.ads \
+ ada/hostparm.ads ada/lib.ads ada/namet.ads ada/nlists.ads \
+ ada/nlists.adb ada/nmake.ads ada/nmake.adb ada/opt.ads ada/output.ads \
+ ada/restrict.ads ada/rident.ads ada/rtsfind.ads ada/sem_aux.ads \
+ ada/sem_util.ads ada/sinfo.ads ada/sinfo.adb ada/sinput.ads \
+ ada/snames.ads ada/stand.ads ada/stringt.ads ada/system.ads \
+ ada/s-exctab.ads ada/s-htable.ads ada/s-imenne.ads ada/s-memory.ads \
+ ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads ada/s-stalib.ads \
+ ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads \
+ ada/table.ads ada/table.adb ada/tbuild.ads ada/tbuild.adb \
+ ada/tree_io.ads ada/ttypes.ads ada/types.ads ada/uintp.ads \
+ ada/uintp.adb ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads
ada/exp_tss.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \
@@ -2177,6 +2183,7 @@ ada/exp_util.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/exp_vfpt.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \
ada/atree.adb ada/casing.ads ada/debug.ads ada/einfo.ads ada/einfo.adb \
+ ada/err_vars.ads ada/errout.ads ada/erroutc.ads ada/eval_fat.ads \
ada/exp_vfpt.ads ada/exp_vfpt.adb ada/gnat.ads ada/g-htable.ads \
ada/hostparm.ads ada/namet.ads ada/nlists.ads ada/nlists.adb \
ada/nmake.ads ada/nmake.adb ada/opt.ads ada/output.ads ada/rtsfind.ads \
@@ -2432,16 +2439,17 @@ ada/interfac.o : ada/interfac.ads ada/system.ads
ada/itypes.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \
ada/atree.adb ada/casing.ads ada/debug.ads ada/einfo.ads ada/einfo.adb \
- ada/exp_tss.ads ada/gnat.ads ada/g-htable.ads ada/hostparm.ads \
- ada/itypes.ads ada/itypes.adb ada/namet.ads ada/nlists.ads ada/opt.ads \
- ada/output.ads ada/rident.ads ada/sem.ads ada/sem_util.ads \
- ada/sinfo.ads ada/sinfo.adb ada/sinput.ads ada/snames.ads ada/stand.ads \
- ada/system.ads ada/s-exctab.ads ada/s-htable.ads ada/s-imenne.ads \
- ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads \
- ada/s-stalib.ads ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads \
- ada/s-wchcon.ads ada/table.ads ada/table.adb ada/targparm.ads \
- ada/tree_io.ads ada/types.ads ada/uintp.ads ada/uintp.adb \
- ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads
+ ada/err_vars.ads ada/errout.ads ada/erroutc.ads ada/exp_tss.ads \
+ ada/gnat.ads ada/g-htable.ads ada/hostparm.ads ada/itypes.ads \
+ ada/itypes.adb ada/namet.ads ada/nlists.ads ada/opt.ads ada/output.ads \
+ ada/rident.ads ada/sem.ads ada/sem_util.ads ada/sinfo.ads ada/sinfo.adb \
+ ada/sinput.ads ada/snames.ads ada/stand.ads ada/system.ads \
+ ada/s-exctab.ads ada/s-htable.ads ada/s-imenne.ads ada/s-memory.ads \
+ ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads ada/s-stalib.ads \
+ ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads \
+ ada/table.ads ada/table.adb ada/targparm.ads ada/tree_io.ads \
+ ada/types.ads ada/uintp.ads ada/uintp.adb ada/unchconv.ads \
+ ada/unchdeal.ads ada/urealp.ads
ada/krunch.o : ada/ada.ads ada/a-unccon.ads ada/hostparm.ads \
ada/krunch.ads ada/krunch.adb ada/system.ads ada/s-exctab.ads \
@@ -2569,11 +2577,12 @@ ada/lib-xref.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/lib.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads ada/a-uncdea.ads \
ada/alloc.ads ada/aspects.ads ada/atree.ads ada/atree.adb \
ada/casing.ads ada/csets.ads ada/debug.ads ada/einfo.ads ada/einfo.adb \
- ada/fname.ads ada/gnat.ads ada/g-byorma.ads ada/g-hesorg.ads \
- ada/g-hesorg.adb ada/hostparm.ads ada/interfac.ads ada/lib.ads \
- ada/lib.adb ada/lib-list.adb ada/lib-sort.adb ada/namet.ads \
- ada/namet.adb ada/nlists.ads ada/nlists.adb ada/opt.ads ada/output.ads \
- ada/scans.ads ada/sinfo.ads ada/sinfo.adb ada/sinput.ads ada/sinput.adb \
+ ada/err_vars.ads ada/errout.ads ada/erroutc.ads ada/fname.ads \
+ ada/gnat.ads ada/g-byorma.ads ada/g-hesorg.ads ada/g-hesorg.adb \
+ ada/hostparm.ads ada/interfac.ads ada/lib.ads ada/lib.adb \
+ ada/lib-list.adb ada/lib-sort.adb ada/namet.ads ada/namet.adb \
+ ada/nlists.ads ada/nlists.adb ada/opt.ads ada/output.ads ada/scans.ads \
+ ada/sinfo.ads ada/sinfo.adb ada/sinput.ads ada/sinput.adb \
ada/snames.ads ada/stand.ads ada/stringt.ads ada/system.ads \
ada/s-exctab.ads ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads \
ada/s-parame.ads ada/s-secsta.ads ada/s-stalib.ads ada/s-stoele.ads \
@@ -2585,18 +2594,19 @@ ada/lib.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads ada/a-uncdea.ads \
ada/live.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \
ada/atree.adb ada/casing.ads ada/csets.ads ada/debug.ads ada/einfo.ads \
- ada/einfo.adb ada/exp_tss.ads ada/fname.ads ada/gnat.ads \
- ada/g-hesorg.ads ada/hostparm.ads ada/lib.ads ada/lib.adb \
- ada/lib-list.adb ada/lib-sort.adb ada/live.ads ada/live.adb \
- ada/namet.ads ada/nlists.ads ada/nlists.adb ada/opt.ads ada/output.ads \
- ada/sem_aux.ads ada/sem_util.ads ada/sinfo.ads ada/sinfo.adb \
- ada/sinput.ads ada/snames.ads ada/stand.ads ada/stringt.ads \
- ada/system.ads ada/s-exctab.ads ada/s-imenne.ads ada/s-memory.ads \
- ada/s-os_lib.ads ada/s-parame.ads ada/s-secsta.ads ada/s-stalib.ads \
- ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads \
- ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads ada/table.adb \
- ada/tree_io.ads ada/types.ads ada/uintp.ads ada/uname.ads \
- ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/widechar.ads
+ ada/einfo.adb ada/err_vars.ads ada/errout.ads ada/erroutc.ads \
+ ada/exp_tss.ads ada/fname.ads ada/gnat.ads ada/g-hesorg.ads \
+ ada/hostparm.ads ada/lib.ads ada/lib.adb ada/lib-list.adb \
+ ada/lib-sort.adb ada/live.ads ada/live.adb ada/namet.ads ada/nlists.ads \
+ ada/nlists.adb ada/opt.ads ada/output.ads ada/sem_aux.ads \
+ ada/sem_util.ads ada/sinfo.ads ada/sinfo.adb ada/sinput.ads \
+ ada/snames.ads ada/stand.ads ada/stringt.ads ada/system.ads \
+ ada/s-exctab.ads ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads \
+ ada/s-parame.ads ada/s-secsta.ads ada/s-stalib.ads ada/s-stoele.ads \
+ ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads \
+ ada/s-wchcon.ads ada/table.ads ada/table.adb ada/tree_io.ads \
+ ada/types.ads ada/uintp.ads ada/uname.ads ada/unchconv.ads \
+ ada/unchdeal.ads ada/urealp.ads ada/widechar.ads
ada/namet-sp.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/alloc.ads ada/debug.ads ada/gnat.ads \
@@ -2733,22 +2743,23 @@ ada/par.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads ada/a-uncdea.ads \
ada/par_sco.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \
ada/atree.adb ada/casing.ads ada/csets.ads ada/debug.ads ada/einfo.ads \
- ada/err_vars.ads ada/errout.ads ada/erroutc.ads ada/fname.ads \
- ada/gnat.ads ada/g-byorma.ads ada/g-hesorg.ads ada/g-hesorg.adb \
- ada/g-htable.ads ada/g-table.ads ada/g-table.adb ada/hostparm.ads \
- ada/lib.ads ada/lib.adb ada/lib-list.adb ada/lib-sort.adb \
- ada/lib-util.ads ada/lib-util.adb ada/namet.ads ada/nlists.ads \
- ada/nlists.adb ada/opt.ads ada/osint.ads ada/osint-c.ads ada/output.ads \
- ada/par_sco.ads ada/par_sco.adb ada/put_scos.ads ada/put_scos.adb \
- ada/scans.ads ada/scos.ads ada/scos.adb ada/sinfo.ads ada/sinfo.adb \
- ada/sinput.ads ada/sinput.adb ada/snames.ads ada/stand.ads \
- ada/stringt.ads ada/system.ads ada/s-exctab.ads ada/s-htable.ads \
- ada/s-htable.adb ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads \
- ada/s-parame.ads ada/s-secsta.ads ada/s-stalib.ads ada/s-stoele.ads \
- ada/s-stoele.adb ada/s-strhas.ads ada/s-string.ads ada/s-traent.ads \
- ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads ada/table.adb \
- ada/tree_io.ads ada/types.ads ada/uintp.ads ada/uname.ads \
- ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/widechar.ads
+ ada/err_vars.ads ada/errout.ads ada/erroutc.ads ada/exp_tss.ads \
+ ada/fname.ads ada/gnat.ads ada/g-byorma.ads ada/g-hesorg.ads \
+ ada/g-hesorg.adb ada/g-htable.ads ada/g-table.ads ada/g-table.adb \
+ ada/hostparm.ads ada/lib.ads ada/lib.adb ada/lib-list.adb \
+ ada/lib-sort.adb ada/lib-util.ads ada/lib-util.adb ada/namet.ads \
+ ada/nlists.ads ada/nlists.adb ada/opt.ads ada/osint.ads ada/osint-c.ads \
+ ada/output.ads ada/par_sco.ads ada/par_sco.adb ada/put_scos.ads \
+ ada/put_scos.adb ada/scans.ads ada/scos.ads ada/scos.adb ada/sem.ads \
+ ada/sem_util.ads ada/sinfo.ads ada/sinfo.adb ada/sinput.ads \
+ ada/sinput.adb ada/snames.ads ada/stand.ads ada/stringt.ads \
+ ada/system.ads ada/s-exctab.ads ada/s-htable.ads ada/s-htable.adb \
+ ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads \
+ ada/s-secsta.ads ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb \
+ ada/s-strhas.ads ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads \
+ ada/s-wchcon.ads ada/table.ads ada/table.adb ada/tree_io.ads \
+ ada/types.ads ada/uintp.ads ada/uname.ads ada/unchconv.ads \
+ ada/unchdeal.ads ada/urealp.ads ada/widechar.ads
ada/prep.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/alloc.ads ada/casing.ads ada/csets.ads \
@@ -2801,20 +2812,20 @@ ada/put_scos.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/repinfo.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \
ada/atree.adb ada/casing.ads ada/csets.ads ada/debug.ads ada/einfo.ads \
- ada/einfo.adb ada/fname.ads ada/gnat.ads ada/g-byorma.ads \
- ada/g-hesorg.ads ada/g-htable.ads ada/hostparm.ads ada/lib.ads \
- ada/lib.adb ada/lib-list.adb ada/lib-sort.adb ada/namet.ads \
- ada/nlists.ads ada/opt.ads ada/output.ads ada/output.adb \
- ada/repinfo.ads ada/repinfo.adb ada/scans.ads ada/sinfo.ads \
- ada/sinfo.adb ada/sinput.ads ada/sinput.adb ada/snames.ads \
- ada/stand.ads ada/stringt.ads ada/system.ads ada/s-exctab.ads \
- ada/s-htable.ads ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads \
- ada/s-parame.ads ada/s-secsta.ads ada/s-soflin.ads ada/s-stache.ads \
- ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads \
- ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads \
- ada/table.adb ada/tree_io.ads ada/types.ads ada/uintp.ads ada/uintp.adb \
- ada/uname.ads ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads \
- ada/widechar.ads
+ ada/einfo.adb ada/err_vars.ads ada/errout.ads ada/erroutc.ads \
+ ada/fname.ads ada/gnat.ads ada/g-byorma.ads ada/g-hesorg.ads \
+ ada/g-htable.ads ada/hostparm.ads ada/lib.ads ada/lib.adb \
+ ada/lib-list.adb ada/lib-sort.adb ada/namet.ads ada/nlists.ads \
+ ada/opt.ads ada/output.ads ada/output.adb ada/repinfo.ads \
+ ada/repinfo.adb ada/scans.ads ada/sinfo.ads ada/sinfo.adb \
+ ada/sinput.ads ada/sinput.adb ada/snames.ads ada/stand.ads \
+ ada/stringt.ads ada/system.ads ada/s-exctab.ads ada/s-htable.ads \
+ ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads \
+ ada/s-secsta.ads ada/s-soflin.ads ada/s-stache.ads ada/s-stalib.ads \
+ ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads \
+ ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads ada/table.adb \
+ ada/tree_io.ads ada/types.ads ada/uintp.ads ada/uintp.adb ada/uname.ads \
+ ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/widechar.ads
ada/restrict.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/aspects.adb \
@@ -3138,52 +3149,53 @@ ada/sem_attr.o : ada/ada.ads ada/a-charac.ads ada/a-chlat1.ads \
ada/aspects.ads ada/atree.ads ada/atree.adb ada/casing.ads \
ada/checks.ads ada/checks.adb ada/csets.ads ada/debug.ads \
ada/debug_a.ads ada/einfo.ads ada/einfo.adb ada/elists.ads \
- ada/err_vars.ads ada/errout.ads ada/erroutc.ads ada/eval_fat.ads \
- ada/exp_aggr.ads ada/exp_ch11.ads ada/exp_ch2.ads ada/exp_ch4.ads \
- ada/exp_ch6.ads ada/exp_ch7.ads ada/exp_disp.ads ada/exp_dist.ads \
- ada/exp_pakd.ads ada/exp_tss.ads ada/exp_util.ads ada/exp_util.adb \
- ada/expander.ads ada/fname.ads ada/fname-uf.ads ada/freeze.ads \
- ada/get_targ.ads ada/gnat.ads ada/g-byorma.ads ada/g-htable.ads \
- ada/gnatvsn.ads ada/hostparm.ads ada/inline.ads ada/itypes.ads \
- ada/lib.ads ada/lib-load.ads ada/lib-util.ads ada/lib-xref.ads \
- ada/namet.ads ada/namet-sp.ads ada/nlists.ads ada/nlists.adb \
- ada/nmake.ads ada/nmake.adb ada/opt.ads ada/output.ads ada/put_alfa.ads \
- ada/restrict.ads ada/restrict.adb ada/rident.ads ada/rtsfind.ads \
- ada/scans.ads ada/sdefault.ads ada/sem.ads ada/sem.adb ada/sem_aggr.ads \
- ada/sem_attr.ads ada/sem_attr.adb ada/sem_aux.ads ada/sem_aux.adb \
- ada/sem_cat.ads ada/sem_ch10.ads ada/sem_ch11.ads ada/sem_ch12.ads \
- ada/sem_ch13.ads ada/sem_ch2.ads ada/sem_ch3.ads ada/sem_ch4.ads \
- ada/sem_ch5.ads ada/sem_ch6.ads ada/sem_ch7.ads ada/sem_ch8.ads \
- ada/sem_ch9.ads ada/sem_dim.ads ada/sem_disp.ads ada/sem_dist.ads \
- ada/sem_elab.ads ada/sem_elim.ads ada/sem_eval.ads ada/sem_eval.adb \
- ada/sem_intr.ads ada/sem_prag.ads ada/sem_res.ads ada/sem_res.adb \
- ada/sem_type.ads ada/sem_util.ads ada/sem_util.adb ada/sem_warn.ads \
- ada/sinfo.ads ada/sinfo.adb ada/sinfo-cn.ads ada/sinput.ads \
- ada/sinput.adb ada/snames.ads ada/snames.adb ada/sprint.ads \
- ada/stand.ads ada/stringt.ads ada/stringt.adb ada/style.ads \
- ada/styleg.ads ada/styleg.adb ada/stylesw.ads ada/system.ads \
- ada/s-carun8.ads ada/s-exctab.ads ada/s-exctab.adb ada/s-htable.ads \
- ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads \
- ada/s-rident.ads ada/s-secsta.ads ada/s-soflin.ads ada/s-stache.ads \
- ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads \
- ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads \
- ada/table.adb ada/targparm.ads ada/tbuild.ads ada/tbuild.adb \
- ada/tree_io.ads ada/ttypes.ads ada/types.ads ada/types.adb \
- ada/uintp.ads ada/uintp.adb ada/uname.ads ada/unchconv.ads \
- ada/unchdeal.ads ada/urealp.ads ada/urealp.adb ada/validsw.ads \
- ada/widechar.ads
+ ada/elists.adb ada/err_vars.ads ada/errout.ads ada/erroutc.ads \
+ ada/eval_fat.ads ada/exp_aggr.ads ada/exp_ch11.ads ada/exp_ch2.ads \
+ ada/exp_ch4.ads ada/exp_ch6.ads ada/exp_ch7.ads ada/exp_disp.ads \
+ ada/exp_dist.ads ada/exp_pakd.ads ada/exp_tss.ads ada/exp_util.ads \
+ ada/exp_util.adb ada/expander.ads ada/fname.ads ada/fname-uf.ads \
+ ada/freeze.ads ada/get_targ.ads ada/gnat.ads ada/g-byorma.ads \
+ ada/g-htable.ads ada/gnatvsn.ads ada/hostparm.ads ada/inline.ads \
+ ada/itypes.ads ada/lib.ads ada/lib-load.ads ada/lib-util.ads \
+ ada/lib-xref.ads ada/namet.ads ada/namet-sp.ads ada/nlists.ads \
+ ada/nlists.adb ada/nmake.ads ada/nmake.adb ada/opt.ads ada/output.ads \
+ ada/put_alfa.ads ada/restrict.ads ada/restrict.adb ada/rident.ads \
+ ada/rtsfind.ads ada/scans.ads ada/sdefault.ads ada/sem.ads ada/sem.adb \
+ ada/sem_aggr.ads ada/sem_attr.ads ada/sem_attr.adb ada/sem_aux.ads \
+ ada/sem_aux.adb ada/sem_cat.ads ada/sem_ch10.ads ada/sem_ch11.ads \
+ ada/sem_ch12.ads ada/sem_ch13.ads ada/sem_ch2.ads ada/sem_ch3.ads \
+ ada/sem_ch4.ads ada/sem_ch5.ads ada/sem_ch6.ads ada/sem_ch7.ads \
+ ada/sem_ch8.ads ada/sem_ch9.ads ada/sem_dim.ads ada/sem_disp.ads \
+ ada/sem_dist.ads ada/sem_elab.ads ada/sem_elim.ads ada/sem_eval.ads \
+ ada/sem_eval.adb ada/sem_intr.ads ada/sem_prag.ads ada/sem_res.ads \
+ ada/sem_res.adb ada/sem_type.ads ada/sem_util.ads ada/sem_util.adb \
+ ada/sem_warn.ads ada/sinfo.ads ada/sinfo.adb ada/sinfo-cn.ads \
+ ada/sinput.ads ada/sinput.adb ada/snames.ads ada/snames.adb \
+ ada/sprint.ads ada/stand.ads ada/stringt.ads ada/stringt.adb \
+ ada/style.ads ada/styleg.ads ada/styleg.adb ada/stylesw.ads \
+ ada/system.ads ada/s-carun8.ads ada/s-exctab.ads ada/s-exctab.adb \
+ ada/s-htable.ads ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads \
+ ada/s-parame.ads ada/s-rident.ads ada/s-secsta.ads ada/s-soflin.ads \
+ ada/s-stache.ads ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb \
+ ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads \
+ ada/table.ads ada/table.adb ada/targparm.ads ada/tbuild.ads \
+ ada/tbuild.adb ada/tree_io.ads ada/ttypes.ads ada/types.ads \
+ ada/types.adb ada/uintp.ads ada/uintp.adb ada/uname.ads \
+ ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/urealp.adb \
+ ada/validsw.ads ada/widechar.ads
ada/sem_aux.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \
ada/atree.adb ada/casing.ads ada/debug.ads ada/einfo.ads ada/einfo.adb \
- ada/hostparm.ads ada/namet.ads ada/nlists.ads ada/opt.ads \
- ada/output.ads ada/sem_aux.ads ada/sem_aux.adb ada/sinfo.ads \
- ada/sinfo.adb ada/sinput.ads ada/snames.ads ada/stand.ads \
- ada/system.ads ada/s-exctab.ads ada/s-imenne.ads ada/s-memory.ads \
- ada/s-os_lib.ads ada/s-parame.ads ada/s-stalib.ads ada/s-string.ads \
- ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads \
- ada/table.adb ada/tree_io.ads ada/types.ads ada/uintp.ads \
- ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads
+ ada/err_vars.ads ada/errout.ads ada/erroutc.ads ada/hostparm.ads \
+ ada/namet.ads ada/nlists.ads ada/opt.ads ada/output.ads ada/sem_aux.ads \
+ ada/sem_aux.adb ada/sinfo.ads ada/sinfo.adb ada/sinput.ads \
+ ada/snames.ads ada/stand.ads ada/system.ads ada/s-exctab.ads \
+ ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads \
+ ada/s-stalib.ads ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads \
+ ada/s-wchcon.ads ada/table.ads ada/table.adb ada/tree_io.ads \
+ ada/types.ads ada/uintp.ads ada/unchconv.ads ada/unchdeal.ads \
+ ada/urealp.ads
ada/sem_case.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \
@@ -3889,15 +3901,16 @@ ada/sem_res.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/sem_scil.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \
ada/atree.adb ada/casing.ads ada/debug.ads ada/einfo.ads ada/einfo.adb \
- ada/hostparm.ads ada/namet.ads ada/nlists.ads ada/nlists.adb \
- ada/opt.ads ada/output.ads ada/rtsfind.ads ada/scil_ll.ads \
- ada/sem_aux.ads ada/sem_scil.ads ada/sem_scil.adb ada/sinfo.ads \
- ada/sinfo.adb ada/sinput.ads ada/snames.ads ada/stand.ads \
- ada/system.ads ada/s-exctab.ads ada/s-imenne.ads ada/s-memory.ads \
- ada/s-os_lib.ads ada/s-parame.ads ada/s-stalib.ads ada/s-string.ads \
- ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads \
- ada/table.adb ada/tree_io.ads ada/types.ads ada/uintp.ads \
- ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads
+ ada/err_vars.ads ada/errout.ads ada/erroutc.ads ada/hostparm.ads \
+ ada/namet.ads ada/nlists.ads ada/nlists.adb ada/opt.ads ada/output.ads \
+ ada/rtsfind.ads ada/scil_ll.ads ada/sem_aux.ads ada/sem_scil.ads \
+ ada/sem_scil.adb ada/sinfo.ads ada/sinfo.adb ada/sinput.ads \
+ ada/snames.ads ada/stand.ads ada/system.ads ada/s-exctab.ads \
+ ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads \
+ ada/s-stalib.ads ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads \
+ ada/s-wchcon.ads ada/table.ads ada/table.adb ada/tree_io.ads \
+ ada/types.ads ada/uintp.ads ada/unchconv.ads ada/unchdeal.ads \
+ ada/urealp.ads
ada/sem_smem.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \
@@ -3977,8 +3990,9 @@ ada/sem_util.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/sem_vfpt.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/alloc.ads ada/atree.ads ada/cstand.ads \
- ada/debug.ads ada/einfo.ads ada/einfo.adb ada/hostparm.ads \
- ada/namet.ads ada/nlists.ads ada/opt.ads ada/output.ads ada/rident.ads \
+ ada/debug.ads ada/einfo.ads ada/einfo.adb ada/err_vars.ads \
+ ada/errout.ads ada/erroutc.ads ada/hostparm.ads ada/namet.ads \
+ ada/nlists.ads ada/opt.ads ada/output.ads ada/rident.ads \
ada/sem_vfpt.ads ada/sem_vfpt.adb ada/sinfo.ads ada/snames.ads \
ada/stand.ads ada/system.ads ada/s-exctab.ads ada/s-imenne.ads \
ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads \
@@ -4111,22 +4125,23 @@ ada/snames.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/sprint.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \
ada/atree.adb ada/casing.ads ada/csets.ads ada/debug.ads ada/einfo.ads \
- ada/einfo.adb ada/exp_tss.ads ada/fname.ads ada/gnat.ads \
- ada/g-byorma.ads ada/g-hesorg.ads ada/g-htable.ads ada/hostparm.ads \
- ada/interfac.ads ada/lib.ads ada/lib.adb ada/lib-list.adb \
- ada/lib-sort.adb ada/namet.ads ada/namet.adb ada/nlists.ads \
- ada/nlists.adb ada/opt.ads ada/output.ads ada/output.adb \
- ada/rtsfind.ads ada/scans.ads ada/sem_eval.ads ada/sem_util.ads \
- ada/sinfo.ads ada/sinfo.adb ada/sinput.ads ada/sinput.adb \
- ada/sinput-d.ads ada/snames.ads ada/sprint.ads ada/sprint.adb \
- ada/stand.ads ada/stringt.ads ada/stringt.adb ada/system.ads \
- ada/s-exctab.ads ada/s-htable.ads ada/s-imenne.ads ada/s-memory.ads \
- ada/s-os_lib.ads ada/s-parame.ads ada/s-secsta.ads ada/s-soflin.ads \
- ada/s-stache.ads ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb \
- ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads \
- ada/table.ads ada/table.adb ada/tree_io.ads ada/types.ads ada/uintp.ads \
- ada/uintp.adb ada/uname.ads ada/unchconv.ads ada/unchdeal.ads \
- ada/urealp.ads ada/urealp.adb ada/widechar.ads
+ ada/einfo.adb ada/err_vars.ads ada/errout.ads ada/erroutc.ads \
+ ada/exp_tss.ads ada/fname.ads ada/gnat.ads ada/g-byorma.ads \
+ ada/g-hesorg.ads ada/g-htable.ads ada/hostparm.ads ada/interfac.ads \
+ ada/lib.ads ada/lib.adb ada/lib-list.adb ada/lib-sort.adb ada/namet.ads \
+ ada/namet.adb ada/nlists.ads ada/nlists.adb ada/opt.ads ada/output.ads \
+ ada/output.adb ada/rtsfind.ads ada/scans.ads ada/sem_eval.ads \
+ ada/sem_util.ads ada/sinfo.ads ada/sinfo.adb ada/sinput.ads \
+ ada/sinput.adb ada/sinput-d.ads ada/snames.ads ada/sprint.ads \
+ ada/sprint.adb ada/stand.ads ada/stringt.ads ada/stringt.adb \
+ ada/system.ads ada/s-exctab.ads ada/s-htable.ads ada/s-imenne.ads \
+ ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads ada/s-secsta.ads \
+ ada/s-soflin.ads ada/s-stache.ads ada/s-stalib.ads ada/s-stoele.ads \
+ ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads \
+ ada/s-wchcon.ads ada/table.ads ada/table.adb ada/tree_io.ads \
+ ada/types.ads ada/uintp.ads ada/uintp.adb ada/uname.ads \
+ ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/urealp.adb \
+ ada/widechar.ads
ada/stand.o : ada/ada.ads ada/a-unccon.ads ada/a-uncdea.ads ada/stand.ads \
ada/stand.adb ada/system.ads ada/s-exctab.ads ada/s-os_lib.ads \
@@ -4230,7 +4245,8 @@ ada/targparm.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/tbuild.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \
ada/atree.adb ada/casing.ads ada/csets.ads ada/debug.ads ada/einfo.ads \
- ada/einfo.adb ada/elists.ads ada/elists.adb ada/fname.ads ada/gnat.ads \
+ ada/einfo.adb ada/elists.ads ada/elists.adb ada/err_vars.ads \
+ ada/errout.ads ada/erroutc.ads ada/fname.ads ada/gnat.ads \
ada/g-hesorg.ads ada/g-htable.ads ada/hostparm.ads ada/interfac.ads \
ada/lib.ads ada/lib.adb ada/lib-list.adb ada/lib-sort.adb ada/namet.ads \
ada/namet.adb ada/nlists.ads ada/nmake.ads ada/nmake.adb ada/opt.ads \
@@ -4283,7 +4299,8 @@ ada/tree_io.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/treepr.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \
ada/atree.adb ada/casing.ads ada/csets.ads ada/debug.ads ada/einfo.ads \
- ada/einfo.adb ada/elists.ads ada/elists.adb ada/fname.ads ada/gnat.ads \
+ ada/einfo.adb ada/elists.ads ada/elists.adb ada/err_vars.ads \
+ ada/errout.ads ada/erroutc.ads ada/fname.ads ada/gnat.ads \
ada/g-byorma.ads ada/g-hesorg.ads ada/g-htable.ads ada/hostparm.ads \
ada/lib.ads ada/lib.adb ada/lib-list.adb ada/lib-sort.adb ada/namet.ads \
ada/nlists.ads ada/nlists.adb ada/opt.ads ada/output.ads ada/output.adb \
diff --git a/gcc/ada/gcc-interface/Makefile.in b/gcc/ada/gcc-interface/Makefile.in
index dd71b322415..cfba9a19703 100644
--- a/gcc/ada/gcc-interface/Makefile.in
+++ b/gcc/ada/gcc-interface/Makefile.in
@@ -984,6 +984,33 @@ ifeq ($(strip $(filter-out mips% wrs vx%,$(targ))),)
EXTRA_LIBGNAT_OBJS+=vx_stack_info.o
endif
+ifeq ($(strip $(filter-out arm% linux-androideabi,$(arch) $(osys)-$(word 4,$(targ)))),)
+ LIBGNAT_TARGET_PAIRS = \
+ a-intnam.ads<a-intnam-linux.ads \
+ s-inmaop.adb<s-inmaop-posix.adb \
+ s-intman.adb<s-intman-posix.adb \
+ s-linux.ads<s-linux.ads \
+ s-osinte.adb<s-osinte-android.adb \
+ s-osinte.ads<s-osinte-android.ads \
+ s-osprim.adb<s-osprim-posix.adb \
+ s-taprop.adb<s-taprop-posix.adb \
+ s-taspri.ads<s-taspri-posix-noaltstack.ads \
+ s-tpopsp.adb<s-tpopsp-posix-foreign.adb \
+ system.ads<system-linux-armel.ads \
+ $(DUMMY_SOCKETS_TARGET_PAIRS)
+
+ TOOLS_TARGET_PAIRS = \
+ mlib-tgt-specific.adb<mlib-tgt-specific-linux.adb \
+ indepsw.adb<indepsw-gnu.adb
+
+ GNATRTL_SOCKETS_OBJS =
+ EXTRA_GNATRTL_TASKING_OBJS=s-linux.o
+ EH_MECHANISM=
+ THREADSLIB =
+ GNATLIB_SHARED = gnatlib-shared-dual
+ LIBRARY_VERSION := $(LIB_VERSION)
+endif
+
# Sparc Solaris
ifeq ($(strip $(filter-out sparc% sun solaris%,$(targ))),)
LIBGNAT_TARGET_PAIRS_COMMON = \
@@ -2580,43 +2607,11 @@ install-gnatlib: ../stamp-gnatlib-$(RTSDIR)
$(RM) ../stamp-gnatlib-$(RTSDIR)
touch ../stamp-gnatlib1-$(RTSDIR)
-ifeq ($(strip $(filter-out alpha64 ia64 dec hp vms% openvms% alphavms%,$(subst -, ,$(host)))),)
-OSCONS_CPP=../../$(DECC) -E /comment=as_is -DNATIVE \
- -DTARGET='""$(target)""' $(fsrcpfx)ada/s-oscons-tmplt.c
-
-OSCONS_EXTRACT=../../$(DECC) -DNATIVE \
- -DTARGET='""$(target)""' $(fsrcpfx)ada/s-oscons-tmplt.c ; \
- ld -o s-oscons-tmplt.exe s-oscons-tmplt.obj; \
- ./s-oscons-tmplt.exe > s-oscons-tmplt.s
-
-else
-# GCC_FOR_TARGET has paths relative to the gcc directory, so we need to adjust
-# for running it from $(RTSDIR)
-OSCONS_CC=`echo "$(GCC_FOR_TARGET)" \
- | sed -e 's^\./xgcc^../../xgcc^' -e 's^-B./^-B../../^'`
-OSCONS_CPP=$(OSCONS_CC) $(GNATLIBCFLAGS) -E -C \
- -DTARGET=\"$(target)\" $(fsrcpfx)ada/s-oscons-tmplt.c > s-oscons-tmplt.i
-OSCONS_EXTRACT=$(OSCONS_CC) $(GNATLIBCFLAGS) -S s-oscons-tmplt.i
-endif
+$(RTSDIR)/s-oscons.ads: ../stamp-gnatlib1-$(RTSDIR)
+ $(RM) $(RTSDIR)/s-oscons.ads
+ (cd $(RTSDIR); $(LN_S) ../s-oscons.ads s-oscons.ads)
-./bldtools/oscons/xoscons: xoscons.adb xutil.ads xutil.adb
- -$(MKDIR) ./bldtools/oscons
- $(RM) $(addprefix ./bldtools/oscons/,$(notdir $^))
- $(CP) $^ ./bldtools/oscons
- (cd ./bldtools/oscons ; gnatmake -q xoscons)
-
-$(RTSDIR)/s-oscons.ads: ../stamp-gnatlib1-$(RTSDIR) s-oscons-tmplt.c gsocket.h ./bldtools/oscons/xoscons
- $(RM) $(RTSDIR)/s-oscons-tmplt.i $(RTSDIR)/s-oscons-tmplt.s
- (cd $(RTSDIR) ; \
- $(OSCONS_CPP) ; \
- $(OSCONS_EXTRACT) ; \
- ../bldtools/oscons/xoscons s-oscons)
-
-# Don't use semicolon separated shell commands that involve list expansions.
-# The semicolon triggers a call to DCL on VMS and DCL can't handle command
-# line lengths in excess of 256 characters.
-# Example: cd $(RTSDIR); ar rc libfoo.a $(LONG_LIST_OF_OBJS)
-# is guaranteed to overflow the buffer.
+copy-s-oscons: $(RTSDIR)/s-oscons.ads
gnatlib: ../stamp-gnatlib1-$(RTSDIR) ../stamp-gnatlib2-$(RTSDIR) $(RTSDIR)/s-oscons.ads
# C files
diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c
index c4a40c72cc4..0188ddc4c35 100644
--- a/gcc/ada/gcc-interface/trans.c
+++ b/gcc/ada/gcc-interface/trans.c
@@ -5136,62 +5136,54 @@ gnat_to_gnu (Node_Id gnat_node)
break;
case N_Real_Literal:
+ gnu_result_type = get_unpadded_type (Etype (gnat_node));
+
/* If this is of a fixed-point type, the value we want is the
value of the corresponding integer. */
if (IN (Ekind (Underlying_Type (Etype (gnat_node))), Fixed_Point_Kind))
{
- gnu_result_type = get_unpadded_type (Etype (gnat_node));
gnu_result = UI_To_gnu (Corresponding_Integer_Value (gnat_node),
gnu_result_type);
gcc_assert (!TREE_OVERFLOW (gnu_result));
}
- /* We should never see a Vax_Float type literal, since the front end
- is supposed to transform these using appropriate conversions. */
+ /* Convert the Ureal to a vax float (represented on a signed type). */
else if (Vax_Float (Underlying_Type (Etype (gnat_node))))
- gcc_unreachable ();
+ {
+ gnu_result = UI_To_gnu (Get_Vax_Real_Literal_As_Signed (gnat_node),
+ gnu_result_type);
+ }
else
{
Ureal ur_realval = Realval (gnat_node);
- gnu_result_type = get_unpadded_type (Etype (gnat_node));
+ /* First convert the real value to a machine number if it isn't
+ already. That forces BASE to 2 for non-zero values and simplifies
+ the rest of our logic. */
+
+ if (!Is_Machine_Number (gnat_node))
+ ur_realval
+ = Machine (Base_Type (Underlying_Type (Etype (gnat_node))),
+ ur_realval, Round_Even, gnat_node);
- /* If the real value is zero, so is the result. Otherwise,
- convert it to a machine number if it isn't already. That
- forces BASE to 0 or 2 and simplifies the rest of our logic. */
if (UR_Is_Zero (ur_realval))
gnu_result = convert (gnu_result_type, integer_zero_node);
else
{
- if (!Is_Machine_Number (gnat_node))
- ur_realval
- = Machine (Base_Type (Underlying_Type (Etype (gnat_node))),
- ur_realval, Round_Even, gnat_node);
+ REAL_VALUE_TYPE tmp;
gnu_result
= UI_To_gnu (Numerator (ur_realval), gnu_result_type);
- /* If we have a base of zero, divide by the denominator.
- Otherwise, the base must be 2 and we scale the value, which
- we know can fit in the mantissa of the type (hence the use
- of that type above). */
- if (No (Rbase (ur_realval)))
- gnu_result
- = build_binary_op (RDIV_EXPR,
- get_base_type (gnu_result_type),
- gnu_result,
- UI_To_gnu (Denominator (ur_realval),
- gnu_result_type));
- else
- {
- REAL_VALUE_TYPE tmp;
+ /* The base must be 2 as Machine guarantees this, so we scale
+ the value, which we know can fit in the mantissa of the type
+ (hence the use of that type above). */
- gcc_assert (Rbase (ur_realval) == 2);
- real_ldexp (&tmp, &TREE_REAL_CST (gnu_result),
- - UI_To_Int (Denominator (ur_realval)));
- gnu_result = build_real (gnu_result_type, tmp);
- }
+ gcc_assert (Rbase (ur_realval) == 2);
+ real_ldexp (&tmp, &TREE_REAL_CST (gnu_result),
+ - UI_To_Int (Denominator (ur_realval)));
+ gnu_result = build_real (gnu_result_type, tmp);
}
/* Now see if we need to negate the result. Do it this way to
diff --git a/gcc/ada/gnat1drv.adb b/gcc/ada/gnat1drv.adb
index 47c4b177f01..ee6ca097e78 100644
--- a/gcc/ada/gnat1drv.adb
+++ b/gcc/ada/gnat1drv.adb
@@ -192,14 +192,12 @@ procedure Gnat1drv is
-- Enable all other language checks
- Suppress_Options :=
- (Suppress => (Access_Check => True,
- Alignment_Check => True,
- Division_Check => True,
- Elaboration_Check => True,
- others => False),
- Overflow_Checks_General => Suppressed,
- Overflow_Checks_Assertions => Suppressed);
+ Suppress_Options.Suppress :=
+ (Access_Check => True,
+ Alignment_Check => True,
+ Division_Check => True,
+ Elaboration_Check => True,
+ others => False);
Dynamic_Elaboration_Checks := False;
@@ -328,42 +326,50 @@ procedure Gnat1drv is
Exception_Mechanism := Back_End_Exceptions;
end if;
- -- Set proper status for overflow checks
+ -- Set proper status for overflow check mechanism
- -- If already set (by - gnato or -gnatp) then we have nothing to do
+ -- If already set (by -gnato) then we have nothing to do
if Opt.Suppress_Options.Overflow_Checks_General /= Not_Set then
null;
- -- Otherwise set appropriate default mode. Note: at present we set
- -- SUPPRESSED in all three of the following cases. They are separated
- -- because in the future we may make different choices.
+ -- Otherwise set overflow mode defaults
- -- By default suppress overflow checks in -gnatg mode
+ else
+ -- Otherwise set overflow checks off by default
- elsif GNAT_Mode then
- Suppress_Options.Overflow_Checks_General := Suppressed;
- Suppress_Options.Overflow_Checks_Assertions := Suppressed;
+ Suppress_Options.Suppress (Overflow_Check) := True;
- -- If we have backend divide and overflow checks, then by default
- -- overflow checks are suppressed. Historically this code used to
- -- activate overflow checks, although no target currently has these
- -- flags set, so this was dead code anyway.
+ -- Set appropriate default overflow handling mode. Note: at present
+ -- we set STRICT in all three of the following cases. They are
+ -- separated because in the future we may make different choices.
- elsif Targparm.Backend_Divide_Checks_On_Target
- and
- Targparm.Backend_Overflow_Checks_On_Target
- then
- Suppress_Options.Overflow_Checks_General := Suppressed;
- Suppress_Options.Overflow_Checks_Assertions := Suppressed;
+ -- By default set STRICT mode if -gnatg in effect
- -- Otherwise for now, default is checks are suppressed. This is subject
- -- to change in the future, but for now this is the compatible behavior
- -- with previous versions of GNAT.
+ if GNAT_Mode then
+ Suppress_Options.Overflow_Checks_General := Strict;
+ Suppress_Options.Overflow_Checks_Assertions := Strict;
- else
- Suppress_Options.Overflow_Checks_General := Suppressed;
- Suppress_Options.Overflow_Checks_Assertions := Suppressed;
+ -- If we have backend divide and overflow checks, then by default
+ -- overflow checks are STRICT. Historically this code used to also
+ -- activate overflow checks, although no target currently has these
+ -- flags set, so this was dead code anyway.
+
+ elsif Targparm.Backend_Divide_Checks_On_Target
+ and
+ Targparm.Backend_Overflow_Checks_On_Target
+ then
+ Suppress_Options.Overflow_Checks_General := Strict;
+ Suppress_Options.Overflow_Checks_Assertions := Strict;
+
+ -- Otherwise for now, default is STRICT mode. This may change in the
+ -- future, but for now this is the compatible behavior with previous
+ -- versions of GNAT.
+
+ else
+ Suppress_Options.Overflow_Checks_General := Strict;
+ Suppress_Options.Overflow_Checks_Assertions := Strict;
+ end if;
end if;
-- Set default for atomic synchronization. As this synchronization
diff --git a/gcc/ada/gnat_ugn.texi b/gcc/ada/gnat_ugn.texi
index 2455b880a7b..b9c57e0b57e 100644
--- a/gcc/ada/gnat_ugn.texi
+++ b/gcc/ada/gnat_ugn.texi
@@ -4339,15 +4339,14 @@ inlining, but that is no longer the case.
@item -gnato??
@cindex @option{-gnato??} (@command{gcc})
-Set default overflow checking mode. Here `@code{??}' is two digits, a
-single digit, or nothing. Each digit is one of the digits `@code{0}'
+Set default mode for handling generation of code to avoid intermediate
+arithmetic overflow. Here `@code{??}' is two digits, a
+single digit, or nothing. Each digit is one of the digits `@code{1}'
through `@code{3}':
@itemize @bullet
-@item @code{0}:
-suppress overflow checks (@code{SUPPRESSED})
@item @code{1}:
-all intermediate overflows checked (@code{CHECKED})
+all intermediate overflows checked against base type (@code{STRICT})
@item @code{2}:
minimize intermediate overflows (@code{MINIMIZED})
@item @code{3}:
@@ -4360,10 +4359,15 @@ assertions, and the second within assertions.
If no digits follow the @option{-gnato}, then it is equivalent to
@option{-gnato11},
-causing all intermediate overflows to be checked.
+causing all intermediate overflows to be handled in strict mode.
+
+This switch also causes arithmetic overflow checking to be performed
+(as though pragma @code{Unsuppress (Overflow_Check)} has been specified.
+
+The default if no option @option{-gnato} is given is that overflow handling
+is in @code{STRICT} mode (computations done using the base type), and that
+overflow is not enabled.
-The default if no option @option{-gnato} is given is that overflows are not
-checked, which is equivalent to @option{-gnato00}.
Note that division by zero is a separate check that is not
controlled by this switch (division by zero checking is on by default).
@@ -18348,6 +18352,22 @@ specifies the directory that will hold the harness packages and project file
for the test driver. If the @var{dirname} is a relative path, it is considered
relative to the object directory of the project file.
+@item --separates
+@cindex @option{--separates} (@command{gnattest})
+Bodies of all test routines are generated as separates. This option is
+temporarily provided for compatibility to support the old way of generating test
+skeletons. Its usage is not recommended because at some point the option will be
+abandoned together with this way of generating test packages.
+
+
+@item --transition
+@cindex @option{--transition} (@command{gnattest})
+This allows transition from separate test routines to monolith test packages.
+All matching test routines are overwritten with contents of corresponding
+separates. Note that if separate test routines had any manually added with
+clauses they will be moved to the test package body as is and have to be moved
+by hand.
+
@end table
@option{--tests_root}, @option{--subdir} and @option{--tests-dir} switches are
@@ -18432,8 +18452,11 @@ is located in:
For each package containing visible subprograms, a child test package is
generated. It contains one test routine per tested subprogram. Each
declaration of a test subprogram has a comment specifying which tested
-subprogram it corresponds to. All of the test routines have separate bodies.
-The test routine located at simple-test_data-tests-test_inc_5eaee3.adb contains
+subprogram it corresponds to. Bodies of test routines are placed in test package
+bodies and are surrounded by special comment sections. Those comment sections
+should not be removed or modified in order for gnattest to be able to regenerate
+test packages and keep already written tests in place.
+The test routine Test_Inc_5eaee3 located at simple-test_data-tests.adb contains
a single statement: a call to procedure Assert. It has two arguments:
the Boolean expression we want to check and the diagnosis message to display if
the condition is false.
@@ -18469,8 +18492,9 @@ values can be set by Set_Up routine and used in test routines afterwards.
Bodies of test routines and test_data packages are never overridden after they
have been created once. As long as the name of the subprogram, full expanded Ada
-names, and the order of its parameters is the same, the old test routine will
-fit in its place and no test skeleton will be generated for the subprogram.
+names, and the order of its parameters is the same, and comment sections are
+intact the old test routine will fit in its place and no test skeleton will be
+generated for the subprogram.
This can be demonstrated with the previous example. By uncommenting declaration
and body of function Dec in simple.ads and simple.adb, running
@@ -18487,7 +18511,7 @@ the old test is not replaced with a stub, nor is it lost, but a new test
skeleton is created for function Dec.
The only way of regenerating tests skeletons is to remove the previously created
-tests.
+tests together with corresponding comment sections.
@node Default Test Behavior
@section Default Test Behavior
@@ -18615,7 +18639,7 @@ Gnattest has a special option to run overridden parent tests against objects
of the type which have overriding primitives:
@smallexample
-gnattest --harness-dir=driver --liskov -Ptagged_rec.gpr
+gnattest --harness-dir=driver --validate-type-extensions -Ptagged_rec.gpr
cd driver
gprbuild -Ptest_driver
test_runner
@@ -25599,7 +25623,8 @@ intermediate addition of @code{(A + 1)} raises an overflow error.
The (perhaps surprising) answer is that the Ada language
definition does not answer this question. Instead it leaves
-it up to the implementation to do one of two things:
+it up to the implementation to do one of two things if overflow
+checks are enabled.
@itemize @bullet
@item
@@ -25612,10 +25637,14 @@ subsequent operations.
@noindent
If the compiler chooses the first approach, then the assignment of this
-example will indeed raise @code{Constraint_Error}. But if the compiler
+example will indeed raise @code{Constraint_Error} if overflow checking is
+enabled, or result in erroneous execution if overflow checks are suppressed.
+
+But if the compiler
chooses the second approach, then it can perform both additions yielding
the correct mathematical result, which is in range, so no exception
-will be raised.
+will be raised, and the right result is obtained, regardless of whether
+overflow checks are suppressed.
Note that in the first example an
exception will be raised in either case, since if the compiler
@@ -25680,30 +25709,22 @@ would prefer this precondition to be considered True at run time).
To deal with the portability issue, and with the problem of
mathematical versus run-time intepretation of the expressions in
assertions, GNAT provides comprehensive control over the handling
-of intermediate overflow. GNAT can operate in four modes, and
+of intermediate overflow. GNAT can operate in three modes, and
furthemore, permits separate selection of operating modes for
the expressions within assertions (here the term ``assertions''
is used in the technical sense, which includes preconditions and so forth)
and for expressions appearing outside assertions.
-The four modes are:
+The three modes are:
@itemize @bullet
-@item @i{Checks suppressed} (@code{SUPPRESSED})
-
- This is the normal defined language mode, as specified by a pragma
- @code{Suppress (Overflow_Check)}. If any intermediate overflow occurs,
- then the program execution is erroneous, which means that anything
- could happen. Note in particular, that the result of evaluating
- a precondition may be plain wrong if there is an intermediate
- overflow, as in our examples above.
-
-@item @i{All intermediate overflows checked} (@code{CHECKED})
+@item @i{All intermediate overflows checked} (@code{STRICT})
In this mode, all intermediate results for predefined arithmetic
operators must be in range of the base type. If this is not the
- case a constraint error is raised. This is the normal default mode
- specified by use of the pragma @code{Unsuppress (Overflow_Check)}.
+ case then either an exception is raised (if overflow checks are
+ enabled) or the execution is erroneous (if overflow checks are suppressed).
+ This is the normal default mode.
@item @i{Most intermediate overflows avoided} (@code{MINIMIZED})
@@ -25712,7 +25733,7 @@ The four modes are:
performed for predefined arithmetic operators. This is slightly more
expensive at
run time (compared to suppressing intermediate overflow checks), though
- the cost is minimal on modern 64-bit machines. For the examples given
+ the cost is negligible on modern 64-bit machines. For the examples given
earlier, no intermediate overflows would have resulted in exceptions,
since the intermediate results are all in the range of
@code{Long_Long_Integer} (typically 64-bits on nearly all implementations
@@ -25730,9 +25751,11 @@ The four modes are:
Now the intermediate results are
out of the range of @code{Long_Long_Integer} even though the final result
is in range and the precondition is True (from a mathematical point
- of view). In such a case, operating in this mode, an exception will
- be raised for the intermediate overflow (which is why this mode
- says @i{most} intermediate overflows are avoided).
+ of view). In such a case, operating in this mode, an overflow occurs
+ for the intermediate computation (which is why this mode
+ says @i{most} intermediate overflows are avoided). In this case,
+ an exception is raised if overflow checks are enabled, and the
+ execution is erroneous if overflow checks are suppressed.
@item @i{All intermediate overflows avoided} (@code{ELIMINATED})
@@ -25753,6 +25776,15 @@ The four modes are:
predefined arithmetic operators, meaning that there is never a
conflict between the mathematical view of the assertion, and its
run-time behavior.
+
+ Note that in this mode, the behavior is unaffected by whether or
+ not overflow checks are suppressed, since overflow does not occur.
+ It is possible for gigantic intermediate expressions to raise
+ @code{Storage_Error} as a result of attempting to compute the
+ results of such expressions (e.g. @code{Integer'Last ** Integer'Last})
+ but overflow is impossible.
+
+
@end itemize
@noindent
@@ -25761,9 +25793,10 @@ The four modes are:
aritmetic.
For fixed-point arithmetic, checks can be suppressed. But if checks
- are enabled (any of the three non-suppress modes will enable checks),
+ are enabled
then fixed-point values are always checked for overflow against the
- base type for intermediate expressions.
+ base type for intermediate expressions (that is such checks always
+ operate in the equivalent of @code{STRICT} mode).
For floating-point, on nearly all architectures, @code{Machine_Overflows}
is False, and IEEE infinities are generated, so overflow exceptions
@@ -25779,7 +25812,7 @@ The four modes are:
@section Specifying the Desired Mode
@noindent
-The desired mode of overflow checking can be specified using
+The desired mode of for handling intermediate overflow can be specified using
either the @code{Overflow_Checks} pragma or an equivalent compiler switch.
The pragma has the form
@cindex pragma @code{Overflow_Checks}
@@ -25792,8 +25825,7 @@ The pragma has the form
where @code{MODE} is one of
@itemize @bullet
-@item @code{SUPPRESSED}: suppress overflow checks
-@item @code{CHECKED}: all intermediate overflows checked
+@item @code{STRICT}: intermediate overflows checked (using base type)
@item @code{MINIMIZED}: minimize intermediate overflows
@item @code{ELIMINATED}: eliminate intermediate overflows
@end itemize
@@ -25830,17 +25862,21 @@ configuration pragma, specifying a default for the whole
program, or in a declarative scope, where it applies to the
remaining declarations and statements in that scope.
+Note that pragma @code{Overflow_Checks} does not affect whether
+overflow checks are enabled or suppressed. It only controls the
+method used to compute intermediate values. To control whether
+overflow checking is enabled or suppressed, use pragma @code{Suppress}
+or @code{Unsuppress} in the usual manner
+
Additionally, a compiler switch @option{-gnato?} or @option{-gnato??}
can be used to control the checking mode default (which can be subsequently
-overridden using the pragma form).
+overridden using pragmas).
@cindex @option{-gnato?} (gcc)
@cindex @option{-gnato??} (gcc)
-Here `@code{?}' is one of the digits `@code{0}' through `@code{3}':
+Here `@code{?}' is one of the digits `@code{1}' through `@code{3}':
@itemize @bullet
-@item @code{0}:
-suppress overflow checks (@code{SUPPRESSED})
@item @code{1}:
all intermediate overflows checked (@code{CHECKED})
@item @code{2}:
@@ -25859,6 +25895,11 @@ If no digits follow the @option{-gnato}, then it is equivalent to
@option{-gnato11},
causing all intermediate overflows to be checked.
+In addition to setting the mode used for computation of intermediate
+results, the @code{-gnato} switch also enables overflow checking (which
+is suppressed by default). It thus combines the effect of using
+a pragma @code{Overflow_Checks} and pragma @code{Unsuppress}.
+
@c -------------------------
@node Default Settings
@@ -25867,48 +25908,37 @@ causing all intermediate overflows to be checked.
The default mode for overflow checks is
@smallexample
- General => Suppressed
+ General => Strict
@end smallexample
@noindent
-which suppresses checks inside and outside assertions,
+which causes all computations both inside and outside assertions to use
+the base type. In addition overflow checks are suppressed.
+
This retains compatibility with previous versions of
-GNAT which suppressed overflow checks by default.
+GNAT which suppressed overflow checks by default and always
+used the base type for computation of intermediate results.
The switch @option{-gnato} (with no digits following) is equivalent to
@cindex @option{-gnato} (gcc)
@smallexample
- General => Checked
+ General => Strict
@end smallexample
@noindent
which causes overflow checking of all intermediate overflows
-both inside and outside assertions. This provides compatibility
+both inside and outside assertions against the base type.
+This provides compatibility
with this switch as implemented in previous versions of GNAT.
-The pragma @code{Suppress (Overflow_Check)} sets mode
-
-@smallexample
- General => Suppressed
-@end smallexample
-
-@noindent
-suppressing all overflow checking within and outside
-assertions.
-@cindex @code{Overflow_Check} (argument to pragma Suppress)
-
-The pragam @code{Unsuppress (Overflow_Check)} sets mode
-
-@smallexample
- General => Checked
-@end smallexample
-
-@noindent
-which causes overflow checking of all intermediate overflows.
-This applies both inside and outside assertions.
-@cindex @code{Overflow_Check} (argument to pragma Unsuppress)
+The pragma @code{Suppress (Overflow_Check)} disables overflow
+checking, but it has no effect on the method used for computing
+intermediate results.
+The pragam @code{Unsuppress (Overflow_Check)} enables overflow
+checking, but it has no effect on the method used for computing
+intermediate results.
@c -------------------------
@node Implementation Notes
@@ -25924,12 +25954,7 @@ makes sense if you want to
make sure that your code is compatible with any other possible
Ada implementation. This may be useful in ensuring portability
for code that is to be exported to some other compiler than GNAT.
-It is also appropriate if you intend to turn off checks for
-the final delivered software, since in @code{SUPPRESSED} mode, the
-assumption is that all intermediate results are in range. In
-this situation, it is likely that you are also suppressing
-assertions in the final executable, so in that case it does not
-matter which mode is selected for assertions during development.
+
The Ada standard allows the reassociation of expressions at
the same precedence level if no parentheses are present. For
diff --git a/gcc/ada/gprep.adb b/gcc/ada/gprep.adb
index 0fad22bf7a7..8eb1465bff4 100644
--- a/gcc/ada/gprep.adb
+++ b/gcc/ada/gprep.adb
@@ -23,8 +23,8 @@
-- --
------------------------------------------------------------------------------
+with Atree; use Atree;
with Csets;
-with Err_Vars; use Err_Vars;
with Errutil;
with Namet; use Namet;
with Opt;
@@ -524,13 +524,13 @@ package body GPrep is
-- In verbose mode, if there is no error, report it
- if Opt.Verbose_Mode and then Err_Vars.Total_Errors_Detected = 0 then
+ if Opt.Verbose_Mode and then Total_Errors_Detected = 0 then
Errutil.Finalize (Source_Type => "input");
end if;
-- If we had some errors, delete the output file, and report them
- if Err_Vars.Total_Errors_Detected > 0 then
+ if Total_Errors_Detected > 0 then
if Outfile /= Standard_Output then
Delete (Text_Outfile);
end if;
diff --git a/gcc/ada/gsocket.h b/gcc/ada/gsocket.h
index c364fdb0a54..e21d7142701 100644
--- a/gcc/ada/gsocket.h
+++ b/gcc/ada/gsocket.h
@@ -29,7 +29,7 @@
* *
****************************************************************************/
-#if defined(__nucleus__) || defined(VTHREADS)
+#if defined(__nucleus__) || defined(VTHREADS) || defined(__ANDROID__)
#warning Sockets not supported on these platforms
#undef HAVE_SOCKETS
diff --git a/gcc/ada/impunit.adb b/gcc/ada/impunit.adb
index 712a6885bd8..efeb8960a4e 100644
--- a/gcc/ada/impunit.adb
+++ b/gcc/ada/impunit.adb
@@ -663,10 +663,19 @@ package body Impunit is
return Not_Predefined_Unit;
end if;
- -- Not predefined if file name does not end in .ads. This can
- -- happen when non-standard file names are being used.
-
- if Name_Buffer (Name_Len - 3 .. Name_Len) /= ".ads" then
+ -- To be considered predefined, the file name must end in .ads or .adb.
+ -- File names with other extensions (coming from the use of non-standard
+ -- file naming schemes) can never be predefined.
+
+ -- Note that in the context of a compiler, the .adb case will never
+ -- arise. However it can arise for other tools, e.g. gnatprove uses
+ -- this routine to detect when a construct comes from an instance of
+ -- a generic defined in a predefined unit.
+
+ if Name_Buffer (Name_Len - 3 .. Name_Len) /= ".ads"
+ and then
+ Name_Buffer (Name_Len - 3 .. Name_Len) /= ".adb"
+ then
return Not_Predefined_Unit;
end if;
diff --git a/gcc/ada/init.c b/gcc/ada/init.c
index ad00e148fcc..e7283a20146 100644
--- a/gcc/ada/init.c
+++ b/gcc/ada/init.c
@@ -52,6 +52,10 @@ extern "C" {
#include "vxWorks.h"
#endif
+#ifdef __ANDROID__
+#undef linux
+#endif
+
#ifdef IN_RTS
#include "tconfig.h"
#include "tsystem.h"
diff --git a/gcc/ada/makeutl.adb b/gcc/ada/makeutl.adb
index a2ea435269d..b2a6d53bb48 100644
--- a/gcc/ada/makeutl.adb
+++ b/gcc/ada/makeutl.adb
@@ -24,6 +24,7 @@
------------------------------------------------------------------------------
with ALI; use ALI;
+with Atree; use Atree;
with Debug;
with Err_Vars; use Err_Vars;
with Errutil;
diff --git a/gcc/ada/par-ch4.adb b/gcc/ada/par-ch4.adb
index 352feeaf86e..3cb65791a22 100644
--- a/gcc/ada/par-ch4.adb
+++ b/gcc/ada/par-ch4.adb
@@ -2362,6 +2362,11 @@ package body Ch4 is
Scan_State : Saved_Scan_State;
Node1 : Node_Id;
+ Lparen : constant Boolean := Prev_Token = Tok_Left_Paren;
+ -- Remember if previous token is a left parenthesis. This is used to
+ -- deal with checking whether IF/CASE/FOR expressions appearing as
+ -- primaries require extra parenthesization.
+
begin
-- The loop runs more than once only if misplaced pragmas are found
-- or if a misplaced unary minus is skipped.
@@ -2475,11 +2480,18 @@ package body Ch4 is
return Error;
-- If this looks like an if expression, then treat it that way
- -- with an error message.
+ -- with an error message if not explicitly surrounded by
+ -- parentheses.
elsif Ada_Version >= Ada_2012 then
- Error_Msg_SC ("if expression must be parenthesized");
- return P_If_Expression;
+ Node1 := P_If_Expression;
+
+ if not (Lparen and then Token = Tok_Right_Paren) then
+ Error_Msg
+ ("if expression must be parenthesized", Sloc (Node1));
+ end if;
+
+ return Node1;
-- Otherwise treat as misused identifier
@@ -2507,11 +2519,17 @@ package body Ch4 is
return Error;
-- If this looks like a case expression, then treat it that way
- -- with an error message.
+ -- with an error message if not within parentheses.
elsif Ada_Version >= Ada_2012 then
- Error_Msg_SC ("case expression must be parenthesized");
- return P_Case_Expression;
+ Node1 := P_Case_Expression;
+
+ if not (Lparen and then Token = Tok_Right_Paren) then
+ Error_Msg
+ ("case expression must be parenthesized", Sloc (Node1));
+ end if;
+
+ return Node1;
-- Otherwise treat as misused identifier
@@ -2522,19 +2540,24 @@ package body Ch4 is
-- For [all | some] indicates a quantified expression
when Tok_For =>
-
if Token_Is_At_Start_Of_Line then
Error_Msg_AP ("misplaced loop");
return Error;
elsif Ada_Version >= Ada_2012 then
- Error_Msg_SC ("quantified expression must be parenthesized");
- return P_Quantified_Expression;
+ Node1 := P_Quantified_Expression;
- else
+ if not (Lparen and then Token = Tok_Right_Paren) then
+ Error_Msg
+ ("quantified expression must be parenthesized",
+ Sloc (Node1));
+ end if;
+
+ return Node1;
-- Otherwise treat as misused identifier
+ else
return P_Identifier;
end if;
diff --git a/gcc/ada/par-prag.adb b/gcc/ada/par-prag.adb
index 7dcf94033bb..a59a39b1c00 100644
--- a/gcc/ada/par-prag.adb
+++ b/gcc/ada/par-prag.adb
@@ -1188,6 +1188,7 @@ begin
Pragma_Lock_Free |
Pragma_Locking_Policy |
Pragma_Long_Float |
+ Pragma_Loop_Assertion |
Pragma_Machine_Attribute |
Pragma_Main |
Pragma_Main_Storage |
diff --git a/gcc/ada/par_sco.adb b/gcc/ada/par_sco.adb
index be258bfb8b0..2fdd6c5e8e9 100644
--- a/gcc/ada/par_sco.adb
+++ b/gcc/ada/par_sco.adb
@@ -34,6 +34,8 @@ with Opt; use Opt;
with Output; use Output;
with Put_SCOs;
with SCOs; use SCOs;
+with Sem; use Sem;
+with Sem_Util; use Sem_Util;
with Sinfo; use Sinfo;
with Sinput; use Sinput;
with Snames; use Snames;
@@ -926,9 +928,14 @@ package body Par_SCO is
Sloc_Range (Orig, Start, Dummy);
Index := Condition_Pragma_Hash_Table.Get (Start);
- -- The test here for zero is to deal with possible previous errors
+ -- Index can be zero for boolean expressions that do not have SCOs
+ -- (simple decisions outside of a control flow structure), or in case
+ -- of a previous error.
- if Index /= 0 then
+ if Index = 0 then
+ return;
+
+ else
pragma Assert (SCO_Table.Table (Index).C1 = ' ');
SCO_Table.Table (Index).C2 := Constant_Condition_Code (Val);
end if;
@@ -942,6 +949,17 @@ package body Par_SCO is
Index : Nat;
begin
+ -- Nothing to do if not generating SCO, or if we're not processing the
+ -- original source occurrence of the pragma.
+
+ if not (Generate_SCO
+ and then
+ In_Extended_Main_Source_Unit (Cunit_Entity (Current_Sem_Unit))
+ and then not (In_Instance or In_Inlined_Body))
+ then
+ return;
+ end if;
+
-- Note: the reason we use the Sloc value as the key is that in the
-- generic case, the call to this procedure is made on a copy of the
-- original node, so we can't use the Node_Id value.
@@ -950,7 +968,10 @@ package body Par_SCO is
-- The test here for zero is to deal with possible previous errors
- if Index /= 0 then
+ if Index = 0 then
+ Check_Error_Detected;
+
+ else
declare
T : SCO_Table_Entry renames SCO_Table.Table (Index);
diff --git a/gcc/ada/prepcomp.adb b/gcc/ada/prepcomp.adb
index dd64bcb714b..2cc1c5e684f 100644
--- a/gcc/ada/prepcomp.adb
+++ b/gcc/ada/prepcomp.adb
@@ -23,6 +23,7 @@
-- --
------------------------------------------------------------------------------
+with Atree; use Atree;
with Errout; use Errout;
with Lib.Writ; use Lib.Writ;
with Opt; use Opt;
diff --git a/gcc/ada/prj-part.adb b/gcc/ada/prj-part.adb
index f1166afbb73..5d09dbe6010 100644
--- a/gcc/ada/prj-part.adb
+++ b/gcc/ada/prj-part.adb
@@ -23,6 +23,7 @@
-- --
------------------------------------------------------------------------------
+with Atree; use Atree;
with Err_Vars; use Err_Vars;
with Opt; use Opt;
with Osint; use Osint;
@@ -690,7 +691,7 @@ package body Prj.Part is
-- If there were any kind of error during the parsing, serious
-- or not, then the parsing fails.
- if Err_Vars.Total_Errors_Detected > 0 then
+ if Total_Errors_Detected > 0 then
Project := Empty_Node;
end if;
diff --git a/gcc/ada/prj-proc.adb b/gcc/ada/prj-proc.adb
index cb9d533c765..dc745fe5ca6 100644
--- a/gcc/ada/prj-proc.adb
+++ b/gcc/ada/prj-proc.adb
@@ -23,6 +23,7 @@
-- --
------------------------------------------------------------------------------
+with Atree; use Atree;
with Err_Vars; use Err_Vars;
with Opt; use Opt;
with Osint; use Osint;
@@ -2908,7 +2909,7 @@ package body Prj.Proc is
Process_Imported_Projects (Imported, Limited_With => True);
- if Err_Vars.Total_Errors_Detected = 0 then
+ if Total_Errors_Detected = 0 then
Process_Aggregated_Projects;
end if;
@@ -2938,7 +2939,7 @@ package body Prj.Proc is
end loop;
end if;
- if Err_Vars.Total_Errors_Detected = 0 then
+ if Total_Errors_Detected = 0 then
-- For an aggregate library we add the aggregated projects
-- as imported ones. This is necessary to give visibility
diff --git a/gcc/ada/projects.texi b/gcc/ada/projects.texi
index ed42094df07..79ac6620ad7 100644
--- a/gcc/ada/projects.texi
+++ b/gcc/ada/projects.texi
@@ -1036,10 +1036,10 @@ names in lower case)
@noindent
After building an application or a library it is often required to
-install it into the development environment. This installation is
-required if the library is to be used by another application for
-example. The @command{gprinstall} tool provide an easy way to install
-libraries, executable or object code generated durting the build. The
+install it into the development environment. For instance this step is
+required if the library is to be used by another application.
+The @command{gprinstall} tool provides an easy way to install
+libraries, executable or object code generated during the build. The
@b{Install} package can be used to change the default locations.
The following attributes can be defined in package @code{Install}:
@@ -1073,7 +1073,7 @@ installed. Default is @b{include}.
@item @b{Project_Subdir}
-Subdirectory of @b{Prefix} where the installed project is to be
+Subdirectory of @b{Prefix} where the generated project file is to be
installed. Default is @b{share/gpr}.
@end table
diff --git a/gcc/ada/rtsfind.ads b/gcc/ada/rtsfind.ads
index 5f9c9934ca4..2bfbaa82a36 100644
--- a/gcc/ada/rtsfind.ads
+++ b/gcc/ada/rtsfind.ads
@@ -1762,10 +1762,12 @@ package Rtsfind is
RE_Timed_Task_Entry_Call, -- System.Tasking.Rendezvous
RE_Timed_Selective_Wait, -- System.Tasking.Rendezvous
- RE_Complete_Restricted_Activation, -- System.Tasking.Restricted.Stages
- RE_Create_Restricted_Task, -- System.Tasking.Restricted.Stages
- RE_Complete_Restricted_Task, -- System.Tasking.Restricted.Stages
- RE_Restricted_Terminated, -- System.Tasking.Restricted.Stages
+ RE_Activate_Restricted_Tasks, -- System.Tasking.Restricted.Stages
+ RE_Complete_Restricted_Activation, -- System.Tasking.Restricted.Stages
+ RE_Create_Restricted_Task, -- System.Tasking.Restricted.Stages
+ RE_Create_Restricted_Task_Sequential, -- System.Tasking.Restricted.Stages
+ RE_Complete_Restricted_Task, -- System.Tasking.Restricted.Stages
+ RE_Restricted_Terminated, -- System.Tasking.Restricted.Stages
RE_Abort_Tasks, -- System.Tasking.Stages
RE_Activate_Tasks, -- System.Tasking.Stages
@@ -3054,10 +3056,12 @@ package Rtsfind is
RE_Timed_Task_Entry_Call => System_Tasking_Rendezvous,
RE_Timed_Selective_Wait => System_Tasking_Rendezvous,
- RE_Complete_Restricted_Activation => System_Tasking_Restricted_Stages,
- RE_Create_Restricted_Task => System_Tasking_Restricted_Stages,
- RE_Complete_Restricted_Task => System_Tasking_Restricted_Stages,
- RE_Restricted_Terminated => System_Tasking_Restricted_Stages,
+ RE_Activate_Restricted_Tasks => System_Tasking_Restricted_Stages,
+ RE_Complete_Restricted_Activation => System_Tasking_Restricted_Stages,
+ RE_Create_Restricted_Task => System_Tasking_Restricted_Stages,
+ RE_Create_Restricted_Task_Sequential => System_Tasking_Restricted_Stages,
+ RE_Complete_Restricted_Task => System_Tasking_Restricted_Stages,
+ RE_Restricted_Terminated => System_Tasking_Restricted_Stages,
RE_Abort_Tasks => System_Tasking_Stages,
RE_Activate_Tasks => System_Tasking_Stages,
diff --git a/gcc/ada/s-bignum.adb b/gcc/ada/s-bignum.adb
index cb7a4f6c1be..7cafbf3d5ae 100644
--- a/gcc/ada/s-bignum.adb
+++ b/gcc/ada/s-bignum.adb
@@ -776,7 +776,9 @@ package body System.Bignums is
d : DD;
j : Length;
- qhat : SD;
+ qhat : DD;
+ rhat : DD;
+ temp : DD;
begin
-- Initialize data of left and right operands
@@ -847,26 +849,39 @@ package body System.Bignums is
-- Loop through digits
loop
- -- D3. [Calculate qhat.] If uj = v1, set qhat to b-l; otherwise
- -- set qhat to (uj,uj+1)/v1.
-
- if u (j) = v1 then
- qhat := -1;
- else
- qhat := SD ((u (j) & u (j + 1)) / DD (v1));
- end if;
-
- -- D3 (continued). Now test if v2 * qhat is greater than (uj*b +
- -- uj+1 - qhat*v1)*b + uj+2. If so, decrease qhat by 1 and repeat
- -- this test, which determines at high speed most of the cases in
- -- which the trial value qhat is one too large, and it eliminates
- -- all cases where qhat is two too large.
+ -- Note: In the original printing, step D3 was as follows:
- while DD (v2) * DD (qhat) >
- ((u (j) & u (j + 1)) -
- DD (qhat) * DD (v1)) * b + DD (u (j + 2))
+ -- D3. [Calculate qhat.] If uj = v1, set qhat to b-l; otherwise
+ -- set qhat to (uj,uj+1)/v1. Now test if v2 * qhat is greater than
+ -- (uj*b + uj+1 - qhat*v1)*b + uj+2. If so, decrease qhat by 1 and
+ -- repeat this test
+
+ -- This had a bug not discovered till 1995, see Vol 2 errata:
+ -- http://www-cs-faculty.stanford.edu/~uno/err2-2e.ps.gz. Under
+ -- rare circumstances the expression in the test could overflow.
+ -- This version was further corrected in 2005, see Vol 2 errata:
+ -- http://www-cs-faculty.stanford.edu/~uno/all2-pre.ps.gz.
+ -- The code below is the fixed version of this step.
+
+ -- D3. [Calculate qhat.] Set qhat to (uj,uj+1)/v1 and rhat to
+ -- to (uj,uj+1) mod v1.
+
+ temp := u (j) & u (j + 1);
+ qhat := temp / DD (v1);
+ rhat := temp mod DD (v1);
+
+ -- D3 (continued). Now test if qhat >= b or v2*qhat > (rhat,uj+2):
+ -- if so, decrease qhat by 1, increase rhat by v1, and repeat this
+ -- test if rhat < b. [The test on v2 determines at at high speed
+ -- most of the cases in which the trial value qhat is one too
+ -- large, and eliminates all cases where qhat is two too large.]
+
+ while qhat >= b
+ or else DD (v2) * qhat > LSD (rhat) & u (j + 2)
loop
qhat := qhat - 1;
+ rhat := rhat + DD (v1);
+ exit when rhat >= b;
end loop;
-- D4. [Multiply and subtract.] Replace (uj,uj+1..uj+n) by
@@ -892,7 +907,7 @@ package body System.Bignums is
begin
Borrow := 0;
for K in reverse 1 .. n loop
- Temp := DD (qhat) * DD (v (K)) + DD (Borrow);
+ Temp := qhat * DD (v (K)) + DD (Borrow);
Borrow := MSD (Temp);
if LSD (Temp) > u (j + K) then
@@ -908,7 +923,7 @@ package body System.Bignums is
-- D5. [Test remainder.] Set qj = qhat. If the result of step
-- D4 was negative, we will do the add back step (step D6).
- q (j) := qhat;
+ q (j) := LSD (qhat);
if Negative then
diff --git a/gcc/ada/s-oscons-tmplt.c b/gcc/ada/s-oscons-tmplt.c
index c386a1f0b0b..096488671e0 100644
--- a/gcc/ada/s-oscons-tmplt.c
+++ b/gcc/ada/s-oscons-tmplt.c
@@ -252,14 +252,7 @@ main (void) {
**/
TXT("-- This is the version for " TARGET)
TXT("")
-
-#ifdef HAVE_SOCKETS
-/**
- ** The type definitions for struct hostent components uses Interfaces.C
- **/
-
TXT("with Interfaces.C;")
-#endif
/*
package System.OS_Constants is
diff --git a/gcc/ada/s-osinte-android.adb b/gcc/ada/s-osinte-android.adb
new file mode 100644
index 00000000000..61e1a8a5fc2
--- /dev/null
+++ b/gcc/ada/s-osinte-android.adb
@@ -0,0 +1,118 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . O S _ I N T E R F A C E --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1995-2012, AdaCore --
+-- --
+-- GNAT is free software; you can redistribute it and/or modify it under --
+-- terms of the GNU General Public License as published by the Free Soft- --
+-- ware Foundation; either version 3, or (at your option) any later ver- --
+-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE. --
+-- --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception, --
+-- version 3.1, as published by the Free Software Foundation. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNARL was developed by the GNARL team at Florida State University. --
+-- Extensive contributions were provided by Ada Core Technologies, Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This is an Android version of this package.
+
+pragma Polling (Off);
+-- Turn off polling, we do not want ATC polling to take place during
+-- tasking operations. It causes infinite loops and other problems.
+
+-- This package encapsulates all direct interfaces to OS services
+-- that are needed by children of System.
+
+with Interfaces.C; use Interfaces.C;
+package body System.OS_Interface is
+
+ -----------------
+ -- To_Duration --
+ -----------------
+
+ function To_Duration (TS : timespec) return Duration is
+ begin
+ return Duration (TS.tv_sec) + Duration (TS.tv_nsec) / 10#1#E9;
+ end To_Duration;
+
+ -----------------
+ -- To_Timespec --
+ -----------------
+
+ function To_Timespec (D : Duration) return timespec is
+ S : time_t;
+ F : Duration;
+
+ begin
+ S := time_t (Long_Long_Integer (D));
+ F := D - Duration (S);
+
+ -- If F has negative value due to a round-up, adjust for positive F
+ -- value.
+
+ if F < 0.0 then
+ S := S - 1;
+ F := F + 1.0;
+ end if;
+
+ return timespec'(tv_sec => S,
+ tv_nsec => long (Long_Long_Integer (F * 10#1#E9)));
+ end To_Timespec;
+
+ -------------------
+ -- clock_gettime --
+ -------------------
+
+ function clock_gettime
+ (clock_id : clockid_t;
+ tp : access timespec) return int
+ is
+ pragma Unreferenced (clock_id);
+
+ -- Android/Linux don't have clock_gettime, so use gettimeofday
+
+ use Interfaces;
+
+ type timeval is array (1 .. 2) of C.long;
+
+ procedure timeval_to_duration
+ (T : not null access timeval;
+ sec : not null access C.long;
+ usec : not null access C.long);
+ pragma Import (C, timeval_to_duration, "__gnat_timeval_to_duration");
+
+ Micro : constant := 10**6;
+ sec : aliased C.long;
+ usec : aliased C.long;
+ TV : aliased timeval;
+ Result : int;
+
+ function gettimeofday
+ (Tv : access timeval;
+ Tz : System.Address := System.Null_Address) return int;
+ pragma Import (C, gettimeofday, "gettimeofday");
+
+ begin
+ Result := gettimeofday (TV'Access, System.Null_Address);
+ pragma Assert (Result = 0);
+ timeval_to_duration (TV'Access, sec'Access, usec'Access);
+ tp.all := To_Timespec (Duration (sec) + Duration (usec) / Micro);
+ return Result;
+ end clock_gettime;
+
+end System.OS_Interface;
diff --git a/gcc/ada/s-osinte-android.ads b/gcc/ada/s-osinte-android.ads
new file mode 100644
index 00000000000..bdcf4c7495b
--- /dev/null
+++ b/gcc/ada/s-osinte-android.ads
@@ -0,0 +1,643 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . O S _ I N T E R F A C E --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1995-2012, Free Software Foundation, Inc. --
+-- --
+-- GNAT is free software; you can redistribute it and/or modify it under --
+-- terms of the GNU General Public License as published by the Free Soft- --
+-- ware Foundation; either version 3, or (at your option) any later ver- --
+-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE. --
+-- --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception, --
+-- version 3.1, as published by the Free Software Foundation. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNARL was developed by the GNARL team at Florida State University. --
+-- Extensive contributions were provided by Ada Core Technologies, Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This is an Android version of this package which is based on the
+-- GNU/Linux version
+
+-- This package encapsulates all direct interfaces to OS services
+-- that are needed by the tasking run-time (libgnarl).
+
+-- PLEASE DO NOT add any with-clauses to this package or remove the pragma
+-- Preelaborate. This package is designed to be a bottom-level (leaf) package.
+
+with Ada.Unchecked_Conversion;
+with Interfaces.C;
+with System.Linux;
+with System.OS_Constants;
+
+package System.OS_Interface is
+ pragma Preelaborate;
+
+ subtype int is Interfaces.C.int;
+ subtype char is Interfaces.C.char;
+ subtype short is Interfaces.C.short;
+ subtype long is Interfaces.C.long;
+ subtype unsigned is Interfaces.C.unsigned;
+ subtype unsigned_short is Interfaces.C.unsigned_short;
+ subtype unsigned_long is Interfaces.C.unsigned_long;
+ subtype unsigned_char is Interfaces.C.unsigned_char;
+ subtype plain_char is Interfaces.C.plain_char;
+ subtype size_t is Interfaces.C.size_t;
+
+ -----------
+ -- Errno --
+ -----------
+
+ function errno return int;
+ pragma Import (C, errno, "__get_errno");
+
+ EAGAIN : constant := System.Linux.EAGAIN;
+ EINTR : constant := System.Linux.EINTR;
+ EINVAL : constant := System.Linux.EINVAL;
+ ENOMEM : constant := System.Linux.ENOMEM;
+ EPERM : constant := System.Linux.EPERM;
+ ETIMEDOUT : constant := System.Linux.ETIMEDOUT;
+
+ -------------
+ -- Signals --
+ -------------
+
+ Max_Interrupt : constant := 63;
+ type Signal is new int range 0 .. Max_Interrupt;
+ for Signal'Size use int'Size;
+
+ SIGHUP : constant := System.Linux.SIGHUP;
+ SIGINT : constant := System.Linux.SIGINT;
+ SIGQUIT : constant := System.Linux.SIGQUIT;
+ SIGILL : constant := System.Linux.SIGILL;
+ SIGTRAP : constant := System.Linux.SIGTRAP;
+ SIGIOT : constant := System.Linux.SIGIOT;
+ SIGABRT : constant := System.Linux.SIGABRT;
+ SIGFPE : constant := System.Linux.SIGFPE;
+ SIGKILL : constant := System.Linux.SIGKILL;
+ SIGBUS : constant := System.Linux.SIGBUS;
+ SIGSEGV : constant := System.Linux.SIGSEGV;
+ SIGPIPE : constant := System.Linux.SIGPIPE;
+ SIGALRM : constant := System.Linux.SIGALRM;
+ SIGTERM : constant := System.Linux.SIGTERM;
+ SIGUSR1 : constant := System.Linux.SIGUSR1;
+ SIGUSR2 : constant := System.Linux.SIGUSR2;
+ SIGCLD : constant := System.Linux.SIGCLD;
+ SIGCHLD : constant := System.Linux.SIGCHLD;
+ SIGPWR : constant := System.Linux.SIGPWR;
+ SIGWINCH : constant := System.Linux.SIGWINCH;
+ SIGURG : constant := System.Linux.SIGURG;
+ SIGPOLL : constant := System.Linux.SIGPOLL;
+ SIGIO : constant := System.Linux.SIGIO;
+ SIGLOST : constant := System.Linux.SIGLOST;
+ SIGSTOP : constant := System.Linux.SIGSTOP;
+ SIGTSTP : constant := System.Linux.SIGTSTP;
+ SIGCONT : constant := System.Linux.SIGCONT;
+ SIGTTIN : constant := System.Linux.SIGTTIN;
+ SIGTTOU : constant := System.Linux.SIGTTOU;
+ SIGVTALRM : constant := System.Linux.SIGVTALRM;
+ SIGPROF : constant := System.Linux.SIGPROF;
+ SIGXCPU : constant := System.Linux.SIGXCPU;
+ SIGXFSZ : constant := System.Linux.SIGXFSZ;
+ SIGUNUSED : constant := System.Linux.SIGUNUSED;
+ SIGSTKFLT : constant := System.Linux.SIGSTKFLT;
+ SIGLTHRRES : constant := System.Linux.SIGLTHRRES;
+ SIGLTHRCAN : constant := System.Linux.SIGLTHRCAN;
+ SIGLTHRDBG : constant := System.Linux.SIGLTHRDBG;
+
+ SIGADAABORT : constant := SIGABRT;
+ -- Change this to use another signal for task abort. SIGTERM might be a
+ -- good one.
+
+ type Signal_Set is array (Natural range <>) of Signal;
+
+ Unmasked : constant Signal_Set := (
+ SIGTRAP,
+ -- To enable debugging on multithreaded applications, mark SIGTRAP to
+ -- be kept unmasked.
+
+ SIGBUS,
+
+ SIGTTIN, SIGTTOU, SIGTSTP,
+ -- Keep these three signals unmasked so that background processes and IO
+ -- behaves as normal "C" applications
+
+ SIGPROF,
+ -- To avoid confusing the profiler
+
+ SIGKILL, SIGSTOP,
+ -- These two signals actually can't be masked (POSIX won't allow it)
+
+ SIGLTHRRES, SIGLTHRCAN, SIGLTHRDBG);
+ -- These three signals are used by GNU/LinuxThreads starting from glibc
+ -- 2.1 (future 2.2).
+
+ Reserved : constant Signal_Set := (SIGVTALRM, SIGUNUSED);
+ -- Not clear why these two signals are reserved. Perhaps they are not
+ -- supported by this version of GNU/Linux ???
+
+ type sigset_t is private;
+
+ function sigaddset (set : access sigset_t; sig : Signal) return int;
+ pragma Import (C, sigaddset, "_sigaddset");
+
+ function sigdelset (set : access sigset_t; sig : Signal) return int;
+ pragma Import (C, sigdelset, "_sigdelset");
+
+ function sigfillset (set : access sigset_t) return int;
+ pragma Import (C, sigfillset, "_sigfillset");
+
+ function sigismember (set : access sigset_t; sig : Signal) return int;
+ pragma Import (C, sigismember, "_sigismember");
+
+ function sigemptyset (set : access sigset_t) return int;
+ pragma Import (C, sigemptyset, "_sigemptyset");
+
+ type union_type_3 is new String (1 .. 116);
+ type siginfo_t is record
+ si_signo : int;
+ si_code : int;
+ si_errno : int;
+ X_data : union_type_3;
+ end record;
+ pragma Convention (C, siginfo_t);
+
+ type struct_sigaction is record
+ sa_handler : System.Address;
+ sa_mask : sigset_t;
+ sa_flags : Interfaces.C.unsigned_long;
+ sa_restorer : System.Address;
+ end record;
+ pragma Convention (C, struct_sigaction);
+
+ type struct_sigaction_ptr is access all struct_sigaction;
+
+ SA_SIGINFO : constant := System.Linux.SA_SIGINFO;
+ SA_ONSTACK : constant := System.Linux.SA_ONSTACK;
+
+ SIG_BLOCK : constant := 0;
+ SIG_UNBLOCK : constant := 1;
+ SIG_SETMASK : constant := 2;
+
+ SIG_DFL : constant := 0;
+ SIG_IGN : constant := 1;
+
+ function sigaction
+ (sig : Signal;
+ act : struct_sigaction_ptr;
+ oact : struct_sigaction_ptr) return int;
+ pragma Import (C, sigaction, "sigaction");
+
+ ----------
+ -- Time --
+ ----------
+
+ Time_Slice_Supported : constant Boolean := True;
+ -- Indicates whether time slicing is supported
+
+ type timespec is private;
+
+ type clockid_t is new int;
+
+ function clock_gettime
+ (clock_id : clockid_t;
+ tp : access timespec) return int;
+
+ function To_Duration (TS : timespec) return Duration;
+ pragma Inline (To_Duration);
+
+ function To_Timespec (D : Duration) return timespec;
+ pragma Inline (To_Timespec);
+
+ function sysconf (name : int) return long;
+ pragma Import (C, sysconf);
+
+ SC_CLK_TCK : constant := 2;
+ SC_NPROCESSORS_ONLN : constant := 84;
+
+ -------------------------
+ -- Priority Scheduling --
+ -------------------------
+
+ SCHED_OTHER : constant := 0;
+ SCHED_FIFO : constant := 1;
+ SCHED_RR : constant := 2;
+
+ function To_Target_Priority
+ (Prio : System.Any_Priority)
+ return Interfaces.C.int is (Interfaces.C.int (Prio));
+ -- Maps System.Any_Priority to a POSIX priority
+
+ -------------
+ -- Process --
+ -------------
+
+ type pid_t is private;
+
+ function kill (pid : pid_t; sig : Signal) return int;
+ pragma Import (C, kill, "kill");
+
+ function getpid return pid_t;
+ pragma Import (C, getpid, "getpid");
+
+ -------------
+ -- Threads --
+ -------------
+
+ type Thread_Body is access
+ function (arg : System.Address) return System.Address;
+ pragma Convention (C, Thread_Body);
+
+ function Thread_Body_Access is new
+ Ada.Unchecked_Conversion (System.Address, Thread_Body);
+
+ type pthread_t is new unsigned_long;
+ subtype Thread_Id is pthread_t;
+
+ function To_pthread_t is
+ new Ada.Unchecked_Conversion (unsigned_long, pthread_t);
+
+ type pthread_mutex_t is limited private;
+ type pthread_cond_t is limited private;
+ type pthread_attr_t is limited private;
+ type pthread_mutexattr_t is limited private;
+ type pthread_condattr_t is limited private;
+ type pthread_key_t is private;
+
+ PTHREAD_CREATE_DETACHED : constant := 1;
+
+ PTHREAD_SCOPE_PROCESS : constant := 1;
+ PTHREAD_SCOPE_SYSTEM : constant := 0;
+
+ -- Read/Write lock not supported on Android.
+
+ subtype pthread_rwlock_t is pthread_mutex_t;
+ subtype pthread_rwlockattr_t is pthread_mutexattr_t;
+
+ -----------
+ -- Stack --
+ -----------
+
+ type stack_t is record
+ ss_sp : System.Address;
+ ss_flags : int;
+ ss_size : size_t;
+ end record;
+ pragma Convention (C, stack_t);
+
+ function sigaltstack
+ (ss : not null access stack_t;
+ oss : access stack_t) return int;
+ pragma Import (C, sigaltstack, "sigaltstack");
+
+ Alternate_Stack : aliased System.Address;
+ pragma Import (C, Alternate_Stack, "__gnat_alternate_stack");
+ -- The alternate signal stack for stack overflows
+
+ Alternate_Stack_Size : constant := 16 * 1024;
+ -- This must be in keeping with init.c:__gnat_alternate_stack
+
+ Stack_Base_Available : constant Boolean := False;
+ -- Indicates whether the stack base is available on this target
+
+ function Get_Stack_Base (thread : pthread_t)
+ return Address is (Null_Address);
+ -- This is a dummy procedure to share some GNULLI files
+
+ function Get_Page_Size return size_t;
+ function Get_Page_Size return Address;
+ pragma Import (C, Get_Page_Size, "_getpagesize");
+ -- Returns the size of a page
+
+ PROT_NONE : constant := 0;
+ PROT_READ : constant := 1;
+ PROT_WRITE : constant := 2;
+ PROT_EXEC : constant := 4;
+ PROT_ALL : constant := PROT_READ + PROT_WRITE + PROT_EXEC;
+ PROT_ON : constant := PROT_READ;
+ PROT_OFF : constant := PROT_ALL;
+
+ function mprotect (addr : Address; len : size_t; prot : int) return int;
+ pragma Import (C, mprotect);
+
+ ---------------------------------------
+ -- Nonstandard Thread Initialization --
+ ---------------------------------------
+
+ procedure pthread_init is null;
+ -- This is a dummy procedure to share some GNULLI files
+
+ -------------------------
+ -- POSIX.1c Section 3 --
+ -------------------------
+
+ function sigwait (set : access sigset_t; sig : access Signal) return int;
+ pragma Import (C, sigwait, "sigwait");
+
+ function pthread_kill (thread : pthread_t; sig : Signal) return int;
+ pragma Import (C, pthread_kill, "pthread_kill");
+
+ function pthread_sigmask
+ (how : int;
+ set : access sigset_t;
+ oset : access sigset_t) return int;
+ pragma Import (C, pthread_sigmask, "pthread_sigmask");
+
+ --------------------------
+ -- POSIX.1c Section 11 --
+ --------------------------
+
+ function pthread_mutexattr_init
+ (attr : access pthread_mutexattr_t) return int;
+ pragma Import (C, pthread_mutexattr_init, "pthread_mutexattr_init");
+
+ function pthread_mutexattr_destroy
+ (attr : access pthread_mutexattr_t) return int;
+ pragma Import (C, pthread_mutexattr_destroy, "pthread_mutexattr_destroy");
+
+ function pthread_mutex_init
+ (mutex : access pthread_mutex_t;
+ attr : access pthread_mutexattr_t) return int;
+ pragma Import (C, pthread_mutex_init, "pthread_mutex_init");
+
+ function pthread_mutex_destroy (mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_mutex_destroy, "pthread_mutex_destroy");
+
+ function pthread_mutex_lock (mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_mutex_lock, "pthread_mutex_lock");
+
+ function pthread_mutex_unlock (mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_mutex_unlock, "pthread_mutex_unlock");
+
+ function pthread_condattr_init
+ (attr : access pthread_condattr_t) return int;
+ pragma Import (C, pthread_condattr_init, "pthread_condattr_init");
+
+ function pthread_condattr_destroy
+ (attr : access pthread_condattr_t) return int;
+ pragma Import (C, pthread_condattr_destroy, "pthread_condattr_destroy");
+
+ function pthread_cond_init
+ (cond : access pthread_cond_t;
+ attr : access pthread_condattr_t) return int;
+ pragma Import (C, pthread_cond_init, "pthread_cond_init");
+
+ function pthread_cond_destroy (cond : access pthread_cond_t) return int;
+ pragma Import (C, pthread_cond_destroy, "pthread_cond_destroy");
+
+ function pthread_cond_signal (cond : access pthread_cond_t) return int;
+ pragma Import (C, pthread_cond_signal, "pthread_cond_signal");
+
+ function pthread_cond_wait
+ (cond : access pthread_cond_t;
+ mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_cond_wait, "pthread_cond_wait");
+
+ function pthread_cond_timedwait
+ (cond : access pthread_cond_t;
+ mutex : access pthread_mutex_t;
+ abstime : access timespec) return int;
+ pragma Import (C, pthread_cond_timedwait, "pthread_cond_timedwait");
+
+ Relative_Timed_Wait : constant Boolean := False;
+ -- pthread_cond_timedwait requires an absolute delay time
+
+ --------------------------
+ -- POSIX.1c Section 13 --
+ --------------------------
+
+ PTHREAD_PRIO_PROTECT : constant := 0;
+ PTHREAD_PRIO_INHERIT : constant := 1;
+
+ function pthread_mutexattr_setprotocol
+ (attr : access pthread_mutexattr_t;
+ protocol : int) return int is (0);
+
+ function pthread_mutexattr_setprioceiling
+ (attr : access pthread_mutexattr_t;
+ prioceiling : int) return int is (0);
+
+ type struct_sched_param is record
+ sched_priority : int; -- scheduling priority
+ end record;
+ pragma Convention (C, struct_sched_param);
+
+ function pthread_setschedparam
+ (thread : pthread_t;
+ policy : int;
+ param : access struct_sched_param) return int;
+ pragma Import (C, pthread_setschedparam, "pthread_setschedparam");
+
+ function pthread_attr_setscope
+ (attr : access pthread_attr_t;
+ scope : int) return int;
+ pragma Import (C, pthread_attr_setscope, "pthread_attr_setscope");
+
+ function pthread_attr_setschedpolicy
+ (attr : access pthread_attr_t;
+ policy : int) return int;
+ pragma Import
+ (C, pthread_attr_setschedpolicy, "pthread_attr_setschedpolicy");
+
+ function sched_yield return int;
+ pragma Import (C, sched_yield, "sched_yield");
+
+ ---------------------------
+ -- P1003.1c - Section 16 --
+ ---------------------------
+
+ function pthread_attr_init
+ (attributes : access pthread_attr_t) return int;
+ pragma Import (C, pthread_attr_init, "pthread_attr_init");
+
+ function pthread_attr_destroy
+ (attributes : access pthread_attr_t) return int;
+ pragma Import (C, pthread_attr_destroy, "pthread_attr_destroy");
+
+ function pthread_attr_setdetachstate
+ (attr : access pthread_attr_t;
+ detachstate : int) return int;
+ pragma Import
+ (C, pthread_attr_setdetachstate, "pthread_attr_setdetachstate");
+
+ function pthread_attr_setstacksize
+ (attr : access pthread_attr_t;
+ stacksize : size_t) return int;
+ pragma Import (C, pthread_attr_setstacksize, "pthread_attr_setstacksize");
+
+ function pthread_create
+ (thread : access pthread_t;
+ attributes : access pthread_attr_t;
+ start_routine : Thread_Body;
+ arg : System.Address) return int;
+ pragma Import (C, pthread_create, "pthread_create");
+
+ procedure pthread_exit (status : System.Address);
+ pragma Import (C, pthread_exit, "pthread_exit");
+
+ function pthread_self return pthread_t;
+ pragma Import (C, pthread_self, "pthread_self");
+
+ function lwp_self return System.Address;
+ pragma Import (C, lwp_self, "__gnat_lwp_self");
+
+ --------------------------
+ -- POSIX.1c Section 17 --
+ --------------------------
+
+ function pthread_setspecific
+ (key : pthread_key_t;
+ value : System.Address) return int;
+ pragma Import (C, pthread_setspecific, "pthread_setspecific");
+
+ function pthread_getspecific (key : pthread_key_t) return System.Address;
+ pragma Import (C, pthread_getspecific, "pthread_getspecific");
+
+ type destructor_pointer is access procedure (arg : System.Address);
+ pragma Convention (C, destructor_pointer);
+
+ function pthread_key_create
+ (key : access pthread_key_t;
+ destructor : destructor_pointer) return int;
+ pragma Import (C, pthread_key_create, "pthread_key_create");
+
+ CPU_SETSIZE : constant := 1_024;
+ -- Size of the cpu_set_t mask on most linux systems (SUSE 11 uses 4_096).
+ -- This is kept for backward compatibility (System.Task_Info uses it), but
+ -- the run-time library does no longer rely on static masks, using
+ -- dynamically allocated masks instead.
+
+ type bit_field is array (1 .. CPU_SETSIZE) of Boolean;
+ for bit_field'Size use CPU_SETSIZE;
+ pragma Pack (bit_field);
+ pragma Convention (C, bit_field);
+
+ type cpu_set_t is record
+ bits : bit_field;
+ end record;
+ pragma Convention (C, cpu_set_t);
+
+ type cpu_set_t_ptr is access all cpu_set_t;
+ -- In the run-time library we use this pointer because the size of type
+ -- cpu_set_t varies depending on the glibc version. Hence, objects of type
+ -- cpu_set_t are allocated dynamically using the number of processors
+ -- available in the target machine (value obtained at execution time).
+
+ function CPU_ALLOC (count : size_t) return cpu_set_t_ptr;
+ pragma Import (C, CPU_ALLOC, "__gnat_cpu_alloc");
+ -- Wrapper around the CPU_ALLOC C macro
+
+ function CPU_ALLOC_SIZE (count : size_t) return size_t;
+ pragma Import (C, CPU_ALLOC_SIZE, "__gnat_cpu_alloc_size");
+ -- Wrapper around the CPU_ALLOC_SIZE C macro
+
+ procedure CPU_FREE (cpuset : cpu_set_t_ptr);
+ pragma Import (C, CPU_FREE, "__gnat_cpu_free");
+ -- Wrapper around the CPU_FREE C macro
+
+ procedure CPU_ZERO (count : size_t; cpuset : cpu_set_t_ptr);
+ pragma Import (C, CPU_ZERO, "__gnat_cpu_zero");
+ -- Wrapper around the CPU_ZERO_S C macro
+
+ procedure CPU_SET (cpu : int; count : size_t; cpuset : cpu_set_t_ptr);
+ pragma Import (C, CPU_SET, "__gnat_cpu_set");
+ -- Wrapper around the CPU_SET_S C macro
+
+ function pthread_setaffinity_np
+ (thread : pthread_t;
+ cpusetsize : size_t;
+ cpuset : cpu_set_t_ptr) return int;
+ pragma Import (C, pthread_setaffinity_np, "pthread_setaffinity_np");
+ pragma Weak_External (pthread_setaffinity_np);
+ -- Use a weak symbol because this function may be available or not,
+ -- depending on the version of the system.
+
+ function pthread_attr_setaffinity_np
+ (attr : access pthread_attr_t;
+ cpusetsize : size_t;
+ cpuset : cpu_set_t_ptr) return int;
+ pragma Import (C, pthread_attr_setaffinity_np,
+ "pthread_attr_setaffinity_np");
+ pragma Weak_External (pthread_attr_setaffinity_np);
+ -- Use a weak symbol because this function may be available or not,
+ -- depending on the version of the system.
+
+private
+
+ type sigset_t is
+ -- array (0 .. OS_Constants.SIZEOF_sigset - 1) of unsigned_char;
+ array (1 .. 127) of unsigned_char;
+ pragma Convention (C, sigset_t);
+ for sigset_t'Alignment use Interfaces.C.unsigned_long'Alignment;
+
+ pragma Warnings (Off);
+ for struct_sigaction use record
+ sa_handler at Linux.sa_handler_pos range 0 .. Standard'Address_Size - 1;
+ sa_mask at Linux.sa_mask_pos range 0 .. 1023;
+ sa_flags at Linux.sa_flags_pos range 0 .. Standard'Address_Size - 1;
+ end record;
+ -- We intentionally leave sa_restorer unspecified and let the compiler
+ -- append it after the last field, so disable corresponding warning.
+ pragma Warnings (On);
+
+ type pid_t is new int;
+
+ type time_t is new long;
+
+ type timespec is record
+ tv_sec : time_t;
+ tv_nsec : long;
+ end record;
+ pragma Convention (C, timespec);
+
+ type unsigned_long_long_t is mod 2 ** 64;
+ -- Local type only used to get the alignment of this type below
+
+ subtype char_array is Interfaces.C.char_array;
+
+ type pthread_attr_t is record
+ Data : char_array (1 .. OS_Constants.PTHREAD_ATTR_SIZE);
+ end record;
+ pragma Convention (C, pthread_attr_t);
+ for pthread_attr_t'Alignment use Interfaces.C.unsigned_long'Alignment;
+
+ type pthread_condattr_t is record
+ Data : char_array (1 .. OS_Constants.PTHREAD_CONDATTR_SIZE);
+ end record;
+ pragma Convention (C, pthread_condattr_t);
+ for pthread_condattr_t'Alignment use Interfaces.C.int'Alignment;
+
+ type pthread_mutexattr_t is record
+ Data : char_array (1 .. OS_Constants.PTHREAD_MUTEXATTR_SIZE);
+ end record;
+ pragma Convention (C, pthread_mutexattr_t);
+ for pthread_mutexattr_t'Alignment use Interfaces.C.int'Alignment;
+
+ type pthread_mutex_t is record
+ Data : char_array (1 .. OS_Constants.PTHREAD_MUTEX_SIZE);
+ end record;
+ pragma Convention (C, pthread_mutex_t);
+ for pthread_mutex_t'Alignment use Interfaces.C.unsigned_long'Alignment;
+
+ type pthread_cond_t is record
+ Data : char_array (1 .. OS_Constants.PTHREAD_COND_SIZE);
+ end record;
+ pragma Convention (C, pthread_cond_t);
+ for pthread_cond_t'Alignment use unsigned_long_long_t'Alignment;
+
+ type pthread_key_t is new unsigned;
+
+end System.OS_Interface;
diff --git a/gcc/ada/s-tarest.adb b/gcc/ada/s-tarest.adb
index bba83ab76a9..c765cc0789d 100644
--- a/gcc/ada/s-tarest.adb
+++ b/gcc/ada/s-tarest.adb
@@ -111,6 +111,24 @@ package body System.Tasking.Restricted.Stages is
-- Terminate the calling task.
-- This should only be called by the Task_Wrapper procedure.
+ procedure Create_Restricted_Task
+ (Priority : Integer;
+ Stack_Address : System.Address;
+ Size : System.Parameters.Size_Type;
+ Task_Info : System.Task_Info.Task_Info_Type;
+ CPU : Integer;
+ State : Task_Procedure_Access;
+ Discriminants : System.Address;
+ Elaborated : Access_Boolean;
+ Task_Image : String;
+ Created_Task : Task_Id);
+ -- Code shared between Create_Restricted_Task_Concurrent and
+ -- Create_Restricted_Task_Sequential. See comment of the former in the
+ -- specification of this package.
+
+ procedure Activate_Tasks (Chain : Task_Id);
+ -- Activate the list of tasks started by Chain
+
procedure Init_RTS;
-- This procedure performs the initialization of the GNARL.
-- It consists of initializing the environment task, global locks, and
@@ -301,6 +319,40 @@ package body System.Tasking.Restricted.Stages is
-- Restricted GNARLI --
-----------------------
+ -----------------------------------
+ -- Activate_All_Tasks_Sequential --
+ -----------------------------------
+
+ procedure Activate_All_Tasks_Sequential is
+ begin
+ pragma Assert (Partition_Elaboration_Policy = 'S');
+
+ Activate_Tasks (Tasks_Activation_Chain);
+ Tasks_Activation_Chain := Null_Task;
+ end Activate_All_Tasks_Sequential;
+
+ -------------------------------
+ -- Activate_Restricted_Tasks --
+ -------------------------------
+
+ procedure Activate_Restricted_Tasks
+ (Chain_Access : Activation_Chain_Access) is
+ begin
+ if Partition_Elaboration_Policy = 'S' then
+
+ -- In sequential elaboration policy, the chain must be empty. This
+ -- procedure can be called if the unit has been compiled without
+ -- partition elaboration policy, but the partition has a sequential
+ -- elaboration policy.
+
+ pragma Assert (Chain_Access.T_ID = Null_Task);
+ null;
+ else
+ Activate_Tasks (Chain_Access.T_ID);
+ Chain_Access.T_ID := Null_Task;
+ end if;
+ end Activate_Restricted_Tasks;
+
--------------------
-- Activate_Tasks --
--------------------
@@ -311,7 +363,7 @@ package body System.Tasking.Restricted.Stages is
-- created before the activated task. That satisfies our
-- in-order-of-creation ATCB locking policy.
- procedure Activate_Tasks is
+ procedure Activate_Tasks (Chain : Task_Id) is
Self_ID : constant Task_Id := STPO.Self;
C : Task_Id;
Activate_Prio : System.Any_Priority;
@@ -333,7 +385,7 @@ package body System.Tasking.Restricted.Stages is
-- Activate all the tasks in the chain. Creation of the thread of
-- control was deferred until activation. So create it now.
- C := Tasks_Activation_Chain;
+ C := Chain;
while C /= null loop
if C.Common.State /= Terminated then
pragma Assert (C.Common.State = Unactivated);
@@ -381,10 +433,6 @@ package body System.Tasking.Restricted.Stages is
if Single_Lock then
Unlock_RTS;
end if;
-
- -- Remove the tasks from the chain
-
- Tasks_Activation_Chain := null;
end Activate_Tasks;
------------------------------------
@@ -557,9 +605,70 @@ package body System.Tasking.Restricted.Stages is
-- may be used by the operation of Ada code within the task.
SSL.Create_TSD (Created_Task.Common.Compiler_Data);
+ end Create_Restricted_Task;
+
+ procedure Create_Restricted_Task
+ (Priority : Integer;
+ Stack_Address : System.Address;
+ Size : System.Parameters.Size_Type;
+ Task_Info : System.Task_Info.Task_Info_Type;
+ CPU : Integer;
+ State : Task_Procedure_Access;
+ Discriminants : System.Address;
+ Elaborated : Access_Boolean;
+ Chain : in out Activation_Chain;
+ Task_Image : String;
+ Created_Task : Task_Id)
+ is
+ begin
+ if Partition_Elaboration_Policy = 'S' then
+
+ -- A unit may have been compiled without partition elaboration
+ -- policy, and in this case the compiler will emit calls for the
+ -- default policy (concurrent). But if the partition policy is
+ -- sequential, activation must be deferred.
+
+ Create_Restricted_Task_Sequential
+ (Priority, Stack_Address, Size, Task_Info, CPU, State,
+ Discriminants, Elaborated, Task_Image, Created_Task);
+
+ else
+ Create_Restricted_Task
+ (Priority, Stack_Address, Size, Task_Info, CPU, State,
+ Discriminants, Elaborated, Task_Image, Created_Task);
+
+ -- Append this task to the activation chain
+
+ Created_Task.Common.Activation_Link := Chain.T_ID;
+ Chain.T_ID := Created_Task;
+ end if;
+ end Create_Restricted_Task;
+
+ ---------------------------------------
+ -- Create_Restricted_Task_Sequential --
+ ---------------------------------------
+
+ procedure Create_Restricted_Task_Sequential
+ (Priority : Integer;
+ Stack_Address : System.Address;
+ Size : System.Parameters.Size_Type;
+ Task_Info : System.Task_Info.Task_Info_Type;
+ CPU : Integer;
+ State : Task_Procedure_Access;
+ Discriminants : System.Address;
+ Elaborated : Access_Boolean;
+ Task_Image : String;
+ Created_Task : Task_Id) is
+ begin
+ Create_Restricted_Task (Priority, Stack_Address, Size, Task_Info,
+ CPU, State, Discriminants, Elaborated,
+ Task_Image, Created_Task);
+
+ -- Append this task to the activation chain
+
Created_Task.Common.Activation_Link := Tasks_Activation_Chain;
Tasks_Activation_Chain := Created_Task;
- end Create_Restricted_Task;
+ end Create_Restricted_Task_Sequential;
---------------------------
-- Finalize_Global_Tasks --
diff --git a/gcc/ada/s-tarest.ads b/gcc/ada/s-tarest.ads
index c8769754707..6313be626ab 100644
--- a/gcc/ada/s-tarest.ads
+++ b/gcc/ada/s-tarest.ads
@@ -43,10 +43,6 @@
-- The restricted GNARLI is also composed of System.Protected_Objects and
-- System.Protected_Objects.Single_Entry
-pragma Partition_Elaboration_Policy (Sequential);
--- This package only implements the sequential elaboration policy. This pragma
--- will enforce it (and detect conflicts with user specified policy).
-
with System.Task_Info;
with System.Parameters;
@@ -124,6 +120,13 @@ package System.Tasking.Restricted.Stages is
-- t1S : constant String := "t1";
-- tIP (t1, 3, _chain, t1S, 1);
+ Partition_Elaboration_Policy : Character := 'C';
+ pragma Export (C, Partition_Elaboration_Policy,
+ "__gnat_partition_elaboration_policy");
+ -- Partition elaboration policy. Value can be either 'C' for concurrent,
+ -- which is the default or 'S' for sequential. This value can be modified
+ -- by the binder generated code, before calling elaboration code.
+
procedure Create_Restricted_Task
(Priority : Integer;
Stack_Address : System.Address;
@@ -133,10 +136,12 @@ package System.Tasking.Restricted.Stages is
State : Task_Procedure_Access;
Discriminants : System.Address;
Elaborated : Access_Boolean;
+ Chain : in out Activation_Chain;
Task_Image : String;
Created_Task : Task_Id);
-- Compiler interface only. Do not call from within the RTS.
- -- This must be called to create a new task.
+ -- This must be called to create a new task, when the partition
+ -- elaboration policy is not specified (or is concurrent).
--
-- Priority is the task's priority (assumed to be in the
-- System.Any_Priority'Range)
@@ -165,19 +170,58 @@ package System.Tasking.Restricted.Stages is
-- Elaborated is a pointer to a Boolean that must be set to true on exit
-- if the task could be successfully elaborated.
--
+ -- Chain is a linked list of task that needs to be created. On exit,
+ -- Created_Task.Activation_Link will be Chain.T_ID, and Chain.T_ID will be
+ -- Created_Task (the created task will be linked at the front of Chain).
+ --
-- Task_Image is a string created by the compiler that the run time can
-- store to ease the debugging and the Ada.Task_Identification facility.
--
-- Created_Task is the resulting task.
--
-- This procedure can raise Storage_Error if the task creation fails
+
+ procedure Create_Restricted_Task_Sequential
+ (Priority : Integer;
+ Stack_Address : System.Address;
+ Size : System.Parameters.Size_Type;
+ Task_Info : System.Task_Info.Task_Info_Type;
+ CPU : Integer;
+ State : Task_Procedure_Access;
+ Discriminants : System.Address;
+ Elaborated : Access_Boolean;
+ Task_Image : String;
+ Created_Task : Task_Id);
+ -- Compiler interface only. Do not call from within the RTS.
+ -- This must be called to create a new task, when the sequential partition
+ -- elaboration policy is used.
+ --
+ -- The parameters are the same as Create_Restricted_Task_Concurrent,
+ -- except there is no Chain parameter (for the activation chain), as there
+ -- is only one global activation chain, which is declared in the body of
+ -- this package.
+
+ procedure Activate_Restricted_Tasks
+ (Chain_Access : Activation_Chain_Access);
+ -- Compiler interface only. Do not call from within the RTS.
+ -- This must be called by the creator of a chain of one or more new tasks,
+ -- to activate them. The chain is a linked list that up to this point is
+ -- only known to the task that created them, though the individual tasks
+ -- are already in the All_Tasks_List.
+ --
+ -- The compiler builds the chain in LIFO order (as a stack). Another
+ -- version of this procedure had code to reverse the chain, so as to
+ -- activate the tasks in the order of declaration. This might be nice, but
+ -- it is not needed if priority-based scheduling is supported, since all
+ -- the activated tasks synchronize on the activators lock before they start
+ -- activating and so they should start activating in priority order.
--
- -- Contrary to Create_Task, there is no Chain parameter (for the activation
- -- chain), as there is only one global activation chain, which is declared
- -- in the body of this package.
+ -- When the partition elaboration policy is sequential, this procedure
+ -- does nothing, tasks will be activated at end of elaboration.
- procedure Activate_Tasks;
- pragma Export (C, Activate_Tasks, "__gnat_activate_tasks");
+ procedure Activate_All_Tasks_Sequential;
+ pragma Export (C, Activate_All_Tasks_Sequential,
+ "__gnat_activate_all_tasks");
-- Binder interface only. Do not call from within the RTS. This must be
-- called an the end of the elaboration to activate all tasks, in order
-- to implement the sequential elaboration policy.
diff --git a/gcc/ada/s-tposen.ads b/gcc/ada/s-tposen.ads
index 8c07cfd3ac9..58c6d6d62a5 100644
--- a/gcc/ada/s-tposen.ads
+++ b/gcc/ada/s-tposen.ads
@@ -163,7 +163,6 @@ package System.Tasking.Protected_Objects.Single_Entry is
-- procedure _clean is
-- begin
-- service_entry (_object._object'unchecked_access);
- -- unlock_entry (_object._object'unchecked_access);
-- return;
-- end _clean;
-- begin
diff --git a/gcc/ada/scng.adb b/gcc/ada/scng.adb
index ce644bc0952..e27c91d14f2 100644
--- a/gcc/ada/scng.adb
+++ b/gcc/ada/scng.adb
@@ -23,8 +23,8 @@
-- --
------------------------------------------------------------------------------
+with Atree; use Atree;
with Csets; use Csets;
-with Err_Vars; use Err_Vars;
with Hostparm; use Hostparm;
with Namet; use Namet;
with Opt; use Opt;
diff --git a/gcc/ada/sdefault.ads b/gcc/ada/sdefault.ads
index 21745fbb674..492e7b74da9 100644
--- a/gcc/ada/sdefault.ads
+++ b/gcc/ada/sdefault.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 1992-2009, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
diff --git a/gcc/ada/sem.adb b/gcc/ada/sem.adb
index 6aafad8e059..f3577790f4c 100644
--- a/gcc/ada/sem.adb
+++ b/gcc/ada/sem.adb
@@ -723,29 +723,15 @@ package body Sem is
begin
if Suppress = All_Checks then
declare
- Svg : constant Suppress_Record := Scope_Suppress;
+ Svs : constant Suppress_Array := Scope_Suppress.Suppress;
begin
- Scope_Suppress := Suppress_All;
+ Scope_Suppress.Suppress := (others => True);
Analyze (N);
- Scope_Suppress := Svg;
+ Scope_Suppress.Suppress := Svs;
end;
elsif Suppress = Overflow_Check then
declare
- Svg : constant Overflow_Check_Type :=
- Scope_Suppress.Overflow_Checks_General;
- Sva : constant Overflow_Check_Type :=
- Scope_Suppress.Overflow_Checks_Assertions;
- begin
- Scope_Suppress.Overflow_Checks_General := Suppressed;
- Scope_Suppress.Overflow_Checks_Assertions := Suppressed;
- Analyze (N);
- Scope_Suppress.Overflow_Checks_General := Svg;
- Scope_Suppress.Overflow_Checks_Assertions := Sva;
- end;
-
- else
- declare
Svg : constant Boolean := Scope_Suppress.Suppress (Suppress);
begin
Scope_Suppress.Suppress (Suppress) := True;
@@ -776,25 +762,11 @@ package body Sem is
begin
if Suppress = All_Checks then
declare
- Svg : constant Suppress_Record := Scope_Suppress;
- begin
- Scope_Suppress := Suppress_All;
- Analyze_List (L);
- Scope_Suppress := Svg;
- end;
-
- elsif Suppress = Overflow_Check then
- declare
- Svg : constant Overflow_Check_Type :=
- Scope_Suppress.Overflow_Checks_General;
- Sva : constant Overflow_Check_Type :=
- Scope_Suppress.Overflow_Checks_Assertions;
+ Svs : constant Suppress_Array := Scope_Suppress.Suppress;
begin
- Scope_Suppress.Overflow_Checks_General := Suppressed;
- Scope_Suppress.Overflow_Checks_Assertions := Suppressed;
+ Scope_Suppress.Suppress := (others => True);
Analyze_List (L);
- Scope_Suppress.Overflow_Checks_General := Svg;
- Scope_Suppress.Overflow_Checks_Assertions := Sva;
+ Scope_Suppress.Suppress := Svs;
end;
else
@@ -1051,11 +1023,11 @@ package body Sem is
begin
if Suppress = All_Checks then
declare
- Svg : constant Suppress_Record := Scope_Suppress;
+ Svs : constant Suppress_Array := Scope_Suppress.Suppress;
begin
- Scope_Suppress := Suppress_All;
+ Scope_Suppress.Suppress := (others => True);
Insert_After_And_Analyze (N, M);
- Scope_Suppress := Svg;
+ Scope_Suppress.Suppress := Svs;
end;
else
@@ -1111,11 +1083,11 @@ package body Sem is
begin
if Suppress = All_Checks then
declare
- Svg : constant Suppress_Record := Scope_Suppress;
+ Svs : constant Suppress_Array := Scope_Suppress.Suppress;
begin
- Scope_Suppress := Suppress_All;
+ Scope_Suppress.Suppress := (others => True);
Insert_Before_And_Analyze (N, M);
- Scope_Suppress := Svg;
+ Scope_Suppress.Suppress := Svs;
end;
else
@@ -1170,11 +1142,11 @@ package body Sem is
begin
if Suppress = All_Checks then
declare
- Svg : constant Suppress_Record := Scope_Suppress;
+ Svs : constant Suppress_Array := Scope_Suppress.Suppress;
begin
- Scope_Suppress := Suppress_All;
+ Scope_Suppress.Suppress := (others => True);
Insert_List_After_And_Analyze (N, L);
- Scope_Suppress := Svg;
+ Scope_Suppress.Suppress := Svs;
end;
else
@@ -1228,11 +1200,11 @@ package body Sem is
begin
if Suppress = All_Checks then
declare
- Svg : constant Suppress_Record := Scope_Suppress;
+ Svs : constant Suppress_Array := Scope_Suppress.Suppress;
begin
- Scope_Suppress := Suppress_All;
+ Scope_Suppress.Suppress := (others => True);
Insert_List_Before_And_Analyze (N, L);
- Scope_Suppress := Svg;
+ Scope_Suppress.Suppress := Svs;
end;
else
diff --git a/gcc/ada/sem_attr.adb b/gcc/ada/sem_attr.adb
index 4118087d5f6..7ed94b4d91a 100644
--- a/gcc/ada/sem_attr.adb
+++ b/gcc/ada/sem_attr.adb
@@ -30,6 +30,7 @@ with Casing; use Casing;
with Checks; use Checks;
with Debug; use Debug;
with Einfo; use Einfo;
+with Elists; use Elists;
with Errout; use Errout;
with Eval_Fat;
with Exp_Dist; use Exp_Dist;
@@ -375,6 +376,10 @@ package body Sem_Attr is
pragma No_Return (Error_Attr);
-- Like Error_Attr, but error is posted at the start of the prefix
+ procedure S14_Attribute;
+ -- Called for all attributes defined for formal verification to check
+ -- that the S14_Extensions flag is set.
+
procedure Standard_Attribute (Val : Int);
-- Used to process attributes whose prefix is package Standard which
-- yield values of type Universal_Integer. The attribute reference
@@ -1950,6 +1955,18 @@ package body Sem_Attr is
Set_Etype (N, Standard_Boolean);
end Legal_Formal_Attribute;
+ -------------------
+ -- S14_Attribute --
+ -------------------
+
+ procedure S14_Attribute is
+ begin
+ if not Formal_Extensions then
+ Error_Attr
+ ("attribute % requires the use of debug switch -gnatd.V", N);
+ end if;
+ end S14_Attribute;
+
------------------------
-- Standard_Attribute --
------------------------
@@ -3584,6 +3601,231 @@ package body Sem_Attr is
("prefix of % attribute must be a protected object");
end if;
+ ----------------
+ -- Loop_Entry --
+ ----------------
+
+ when Attribute_Loop_Entry => Loop_Entry : declare
+ procedure Check_References_In_Prefix (Loop_Id : Entity_Id);
+ -- Inspect the prefix for any uses of entities declared within the
+ -- related loop. Loop_Id denotes the loop identifier.
+
+ --------------------------------
+ -- Check_References_In_Prefix --
+ --------------------------------
+
+ procedure Check_References_In_Prefix (Loop_Id : Entity_Id) is
+ Loop_Decl : constant Node_Id := Label_Construct (Parent (Loop_Id));
+
+ function Check_Reference (Nod : Node_Id) return Traverse_Result;
+ -- Determine whether a reference mentions an entity declared
+ -- within the related loop.
+
+ function Declared_Within (Nod : Node_Id) return Boolean;
+ -- Determine whether Nod appears in the subtree of Loop_Decl
+
+ ---------------------
+ -- Check_Reference --
+ ---------------------
+
+ function Check_Reference (Nod : Node_Id) return Traverse_Result is
+ begin
+ if Nkind (Nod) = N_Identifier
+ and then Present (Entity (Nod))
+ and then Declared_Within (Declaration_Node (Entity (Nod)))
+ then
+ Error_Attr
+ ("prefix of attribute % cannot reference local entities",
+ Nod);
+ return Abandon;
+ else
+ return OK;
+ end if;
+ end Check_Reference;
+
+ procedure Check_References is new Traverse_Proc (Check_Reference);
+
+ ---------------------
+ -- Declared_Within --
+ ---------------------
+
+ function Declared_Within (Nod : Node_Id) return Boolean is
+ Stmt : Node_Id;
+
+ begin
+ Stmt := Nod;
+ while Present (Stmt) loop
+ if Stmt = Loop_Decl then
+ return True;
+
+ -- Prevent the search from going too far
+
+ elsif Nkind_In (Stmt, N_Entry_Body,
+ N_Package_Body,
+ N_Package_Declaration,
+ N_Protected_Body,
+ N_Subprogram_Body,
+ N_Task_Body)
+ then
+ exit;
+ end if;
+
+ Stmt := Parent (Stmt);
+ end loop;
+
+ return False;
+ end Declared_Within;
+
+ -- Start of processing for Check_Prefix_For_Local_References
+
+ begin
+ Check_References (P);
+ end Check_References_In_Prefix;
+
+ -- Local variables
+
+ Enclosing_Loop : Node_Id;
+ In_Loop_Assertion : Boolean := False;
+ Loop_Id : Entity_Id := Empty;
+ Scop : Entity_Id;
+ Stmt : Node_Id;
+
+ -- Start of processing for Loop_Entry
+
+ begin
+ S14_Attribute;
+ Check_E1;
+ Analyze (E1);
+
+ -- The prefix must denote an object
+
+ if not Is_Object_Reference (P) then
+ Error_Attr_P ("prefix of attribute % must denote an object");
+ end if;
+
+ -- The prefix cannot be of a limited type because the expansion of
+ -- Loop_Entry must create a constant initialized by the evaluated
+ -- prefix.
+
+ if Is_Immutably_Limited_Type (Etype (P)) then
+ Error_Attr_P ("prefix of attribute % cannot be limited");
+ end if;
+
+ -- The sole argument of a Loop_Entry must be a loop name
+
+ if Is_Entity_Name (E1) then
+ Loop_Id := Entity (E1);
+ end if;
+
+ if No (Loop_Id)
+ or else Ekind (Loop_Id) /= E_Loop
+ or else not In_Open_Scopes (Loop_Id)
+ then
+ Error_Attr ("argument of % must be a valid loop name", E1);
+ return;
+ end if;
+
+ -- Climb the parent chain to verify the location of the attribute and
+ -- find the enclosing loop.
+
+ Stmt := N;
+ while Present (Stmt) loop
+
+ -- Locate the enclosing Loop_Assertion pragma (if any). Note that
+ -- when Loop_Assertion is expanded, we must look for an Assertion
+ -- pragma.
+
+ if Nkind (Original_Node (Stmt)) = N_Pragma
+ and then
+ (Pragma_Name (Original_Node (Stmt)) = Name_Assert
+ or else
+ Pragma_Name (Original_Node (Stmt)) = Name_Loop_Assertion)
+ then
+ In_Loop_Assertion := True;
+
+ -- Locate the enclosing loop (if any). Note that Ada 2012 array
+ -- iteration may be expanded into several nested loops, we are
+ -- interested in the outermost one which has the loop identifier.
+
+ elsif Nkind (Stmt) = N_Loop_Statement
+ and then Present (Identifier (Stmt))
+ then
+ Enclosing_Loop := Stmt;
+ exit;
+
+ -- Prevent the search from going too far
+
+ elsif Nkind_In (Stmt, N_Entry_Body,
+ N_Package_Body,
+ N_Package_Declaration,
+ N_Protected_Body,
+ N_Subprogram_Body,
+ N_Task_Body)
+ then
+ exit;
+ end if;
+
+ Stmt := Parent (Stmt);
+ end loop;
+
+ -- Loop_Entry must appear within a Loop_Assertion pragma
+
+ if not In_Loop_Assertion then
+ Error_Attr
+ ("attribute % must appear within pragma Loop_Assertion", N);
+ end if;
+
+ -- A Loop_Entry that applies to a given loop statement shall not
+ -- appear within a body of accept statement, if this construct is
+ -- itself enclosed by the given loop statement.
+
+ for J in reverse 0 .. Scope_Stack.Last loop
+ Scop := Scope_Stack.Table (J).Entity;
+
+ if Ekind (Scop) = E_Loop and then Scop = Loop_Id then
+ exit;
+
+ elsif Ekind_In (Scop, E_Block, E_Loop, E_Return_Statement) then
+ null;
+
+ else
+ Error_Attr
+ ("cannot appear in program unit or accept statement", N);
+ exit;
+ end if;
+ end loop;
+
+ -- The prefix cannot mention entities declared within the related
+ -- loop because they will not be visible once the prefix is moved
+ -- outside the loop.
+
+ Check_References_In_Prefix (Loop_Id);
+
+ -- The prefix must denote a static entity if the pragma does not
+ -- apply to the innermost enclosing loop statement.
+
+ if Present (Enclosing_Loop)
+ and then Entity (Identifier (Enclosing_Loop)) /= Loop_Id
+ and then not Is_Entity_Name (P)
+ then
+ Error_Attr_P ("prefix of attribute % must denote an entity");
+ end if;
+
+ Set_Etype (N, Etype (P));
+
+ -- Associate the attribute with its related loop
+
+ if No (Loop_Entry_Attributes (Loop_Id)) then
+ Set_Loop_Entry_Attributes (Loop_Id, New_Elmt_List);
+ end if;
+
+ -- A Loop_Entry may be [pre]analyzed several times, depending on the
+ -- context. Ensure that it appears only once in the attributes list
+ -- of the related loop.
+
+ Append_Unique_Elmt (N, Loop_Entry_Attributes (Loop_Id));
+ end Loop_Entry;
+
-------------
-- Machine --
-------------
@@ -6517,7 +6759,7 @@ package body Sem_Attr is
when Attribute_Denorm =>
Fold_Uint
- (N, UI_From_Int (Boolean'Pos (Denorm_On_Target)), True);
+ (N, UI_From_Int (Boolean'Pos (Has_Denormals (P_Type))), True);
---------------------
-- Descriptor_Size --
@@ -6989,6 +7231,15 @@ package body Sem_Attr is
end;
end Length;
+ ----------------
+ -- Loop_Entry --
+ ----------------
+
+ -- This null processing requires an explanatory comment???
+
+ when Attribute_Loop_Entry =>
+ null;
+
-------------
-- Machine --
-------------
@@ -7631,7 +7882,7 @@ package body Sem_Attr is
when Attribute_Signed_Zeros =>
Fold_Uint
- (N, UI_From_Int (Boolean'Pos (Signed_Zeros_On_Target)), Static);
+ (N, UI_From_Int (Boolean'Pos (Has_Signed_Zeros (P_Type))), Static);
----------
-- Size --
diff --git a/gcc/ada/sem_ch10.adb b/gcc/ada/sem_ch10.adb
index 0a90eb2e80a..2f203dc2e83 100644
--- a/gcc/ada/sem_ch10.adb
+++ b/gcc/ada/sem_ch10.adb
@@ -725,6 +725,7 @@ package body Sem_Ch10 is
-- ignore the entire analysis effort
if No (Lib_Unit) then
+ Check_Error_Detected;
return;
else
@@ -2677,7 +2678,7 @@ package body Sem_Ch10 is
-- Abandon processing in case of previous errors
if No (Par_Name) then
- pragma Assert (Serious_Errors_Detected /= 0);
+ Check_Error_Detected;
return;
end if;
end loop;
@@ -5105,7 +5106,7 @@ package body Sem_Ch10 is
-- Abandon processing in case of previous errors
if No (Scope (Uname)) then
- pragma Assert (Serious_Errors_Detected /= 0);
+ Check_Error_Detected;
return;
end if;
diff --git a/gcc/ada/sem_ch13.adb b/gcc/ada/sem_ch13.adb
index 51edb644c1d..cdddfa86e76 100644
--- a/gcc/ada/sem_ch13.adb
+++ b/gcc/ada/sem_ch13.adb
@@ -7292,9 +7292,8 @@ package body Sem_Ch13 is
-- clause in question, then there was some previous error for which
-- we already gave a message, so just return with Comp Empty.
- if No (Comp)
- or else Component_Clause (Comp) /= CC
- then
+ if No (Comp) or else Component_Clause (Comp) /= CC then
+ Check_Error_Detected;
Comp := Empty;
-- Normal case where we have a component clause
@@ -7897,15 +7896,22 @@ package body Sem_Ch13 is
end if;
end if;
- -- Dismiss cases for generic types or types with previous errors
+ -- Dismiss generic types
- if No (UT)
- or else UT = Any_Type
- or else Is_Generic_Type (UT)
- or else Is_Generic_Type (Root_Type (UT))
+ if Is_Generic_Type (T)
+ or else
+ Is_Generic_Type (UT)
+ or else
+ Is_Generic_Type (Root_Type (UT))
then
return;
+ -- Guard against previous errors
+
+ elsif No (UT) or else UT = Any_Type then
+ Check_Error_Detected;
+ return;
+
-- Check case of bit packed array
elsif Is_Array_Type (UT)
diff --git a/gcc/ada/sem_ch2.adb b/gcc/ada/sem_ch2.adb
index efa965eb941..f20a518d4d2 100644
--- a/gcc/ada/sem_ch2.adb
+++ b/gcc/ada/sem_ch2.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2011, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -24,7 +24,6 @@
------------------------------------------------------------------------------
with Atree; use Atree;
-with Errout; use Errout;
with Namet; use Namet;
with Opt; use Opt;
with Restrict; use Restrict;
diff --git a/gcc/ada/sem_ch3.adb b/gcc/ada/sem_ch3.adb
index a3b7f3ee2b9..e6f76e29f1c 100644
--- a/gcc/ada/sem_ch3.adb
+++ b/gcc/ada/sem_ch3.adb
@@ -12078,6 +12078,7 @@ package body Sem_Ch3 is
-- Defend against previous errors
if No (Scalar_Range (Derived_Type)) then
+ Check_Error_Detected;
return;
end if;
diff --git a/gcc/ada/sem_ch4.adb b/gcc/ada/sem_ch4.adb
index 9d63e886aaf..10fd3863af2 100644
--- a/gcc/ada/sem_ch4.adb
+++ b/gcc/ada/sem_ch4.adb
@@ -1921,6 +1921,7 @@ package body Sem_Ch4 is
-- Defend against error of missing expressions from previous error
if No (Then_Expr) then
+ Check_Error_Detected;
return;
end if;
@@ -3917,8 +3918,7 @@ package body Sem_Ch4 is
-- subsequent semantic checks might examine the original node.
Set_Entity (Sel, Comp);
- Rewrite (Selector_Name (N),
- New_Occurrence_Of (Comp, Sloc (N)));
+ Rewrite (Selector_Name (N), New_Occurrence_Of (Comp, Sloc (N)));
Set_Original_Discriminant (Selector_Name (N), Comp);
Set_Etype (N, Etype (Comp));
Check_Implicit_Dereference (N, Etype (Comp));
@@ -3930,9 +3930,9 @@ package body Sem_Ch4 is
elsif Is_Record_Type (Prefix_Type) then
- -- Find component with given name
- -- In an instance, if the node is known as a prefixed call, do
- -- not examine components whose visibility may be accidental.
+ -- Find component with given name. In an instance, if the node is
+ -- known as a prefixed call, do not examine components whose
+ -- visibility may be accidental.
while Present (Comp) and then not Is_Prefixed_Call (N) loop
if Chars (Comp) = Chars (Sel)
diff --git a/gcc/ada/sem_ch5.adb b/gcc/ada/sem_ch5.adb
index b062be948a1..bf1eceb4c2f 100644
--- a/gcc/ada/sem_ch5.adb
+++ b/gcc/ada/sem_ch5.adb
@@ -898,6 +898,7 @@ package body Sem_Ch5 is
-- up, and we just return immediately (defence against previous errors).
if No (HSS) then
+ Check_Error_Detected;
return;
end if;
@@ -942,11 +943,8 @@ package body Sem_Ch5 is
-- identifier and continue, otherwise raise an exception.
if No (Ent) then
- if Total_Errors_Detected /= 0 then
- Set_Identifier (N, Empty);
- else
- raise Program_Error;
- end if;
+ Check_Error_Detected;
+ Set_Identifier (N, Empty);
else
Set_Ekind (Ent, E_Block);
@@ -1398,6 +1396,7 @@ package body Sem_Ch5 is
-- Ignore previous error
if Label_Ent = Any_Id then
+ Check_Error_Detected;
return;
-- We just have a label as the target of a goto
diff --git a/gcc/ada/sem_ch8.adb b/gcc/ada/sem_ch8.adb
index ec94ed627f8..7b937a67ac5 100644
--- a/gcc/ada/sem_ch8.adb
+++ b/gcc/ada/sem_ch8.adb
@@ -709,6 +709,7 @@ package body Sem_Ch8 is
------------------------------
procedure Check_Constrained_Object is
+ Typ : constant Entity_Id := Etype (Nam);
Subt : Entity_Id;
begin
@@ -728,7 +729,21 @@ package body Sem_Ch8 is
-- A renaming of an unchecked union does not have an
-- actual subtype.
- elsif Is_Unchecked_Union (Etype (Nam)) then
+ elsif Is_Unchecked_Union (Typ) then
+ null;
+
+ -- If a record is limited its size is invariant. This is the case
+ -- in particular with record types with an access discirminant
+ -- that are used in iterators. This is an optimization, but it
+ -- also prevents typing anomalies when the prefix is further
+ -- expanded. Limited types with discriminants are included.
+
+ elsif Is_Limited_Record (Typ)
+ or else
+ (Ekind (Typ) = E_Limited_Private_Type
+ and then Has_Discriminants (Typ)
+ and then Is_Access_Type (Etype (First_Discriminant (Typ))))
+ then
null;
else
@@ -738,7 +753,7 @@ package body Sem_Ch8 is
Make_Subtype_Declaration (Loc,
Defining_Identifier => Subt,
Subtype_Indication =>
- Make_Subtype_From_Expr (Nam, Etype (Nam))));
+ Make_Subtype_From_Expr (Nam, Typ)));
Rewrite (Subtype_Mark (N), New_Occurrence_Of (Subt, Loc));
Set_Etype (Nam, Subt);
end if;
diff --git a/gcc/ada/sem_ch9.adb b/gcc/ada/sem_ch9.adb
index a81ea5c6148..9b38f0072fb 100644
--- a/gcc/ada/sem_ch9.adb
+++ b/gcc/ada/sem_ch9.adb
@@ -1470,6 +1470,15 @@ package body Sem_Ch9 is
Analyze (Call);
+ -- An indirect call in this context is illegal. A procedure call that
+ -- does not involve a renaming of an entry is illegal as well, but this
+ -- and other semantic errors are caught during resolution.
+
+ if Nkind (Call) = N_Explicit_Dereference then
+ Error_Msg_N
+ ("entry call or dispatching primitive of interface required ", N);
+ end if;
+
if Is_Non_Empty_List (Statements (N)) then
Analyze_Statements (Statements (N));
end if;
@@ -2027,16 +2036,12 @@ package body Sem_Ch9 is
-- by an aspect/pragma.
declare
- Id : constant Entity_Id :=
- Defining_Identifier (Original_Node (N));
+ Id : constant Entity_Id := Defining_Identifier (Original_Node (N));
-- The warning must be issued on the original identifier in order
-- to deal properly with the case of a single protected object.
Prio_Item : constant Node_Id :=
- Get_Rep_Item
- (Defining_Identifier (N),
- Name_Priority,
- Check_Parents => False);
+ Get_Rep_Item (Def_Id, Name_Priority, False);
begin
if Present (Prio_Item) then
@@ -2065,11 +2070,44 @@ package body Sem_Ch9 is
end if;
end if;
+ -- If the Attach_Handler aspect is specified or the Interrupt_Handler
+ -- aspect is True, then the initial ceiling priority must be in the
+ -- range of System.Interrupt_Priority. It is therefore recommanded
+ -- to use the Interrupt_Priority aspect instead of the Priority aspect.
+
+ if Has_Interrupt_Handler (T) or else Has_Attach_Handler (T) then
+ declare
+ Prio_Item : constant Node_Id :=
+ Get_Rep_Item (Def_Id, Name_Priority, False);
+
+ begin
+ if Present (Prio_Item) then
+
+ -- Aspect case
+
+ if (Nkind (Prio_Item) = N_Aspect_Specification
+ or else From_Aspect_Specification (Prio_Item))
+ and then Chars (Identifier (Prio_Item)) = Name_Priority
+ then
+ Error_Msg_N ("?aspect Interrupt_Priority is preferred "
+ & "in presence of handlers", Prio_Item);
+
+ -- Pragma case
+
+ elsif Nkind (Prio_Item) = N_Pragma
+ and then Pragma_Name (Prio_Item) = Name_Priority
+ then
+ Error_Msg_N ("?pragma Interrupt_Priority is preferred "
+ & "in presence of handlers", Prio_Item);
+ end if;
+ end if;
+ end;
+ end if;
+
-- Case of a completion of a private declaration
- if T /= Def_Id
- and then Is_Private_Type (Def_Id)
- then
+ if T /= Def_Id and then Is_Private_Type (Def_Id) then
+
-- Deal with preelaborable initialization. Note that this processing
-- is done by Process_Full_View, but as can be seen below, in this
-- case the call to Process_Full_View is skipped if any serious
@@ -2317,9 +2355,7 @@ package body Sem_Ch9 is
-- the first parameter of Entry_Id since it is the interface
-- controlling formal.
- if Ada_Version >= Ada_2012
- and then Is_Disp_Req
- then
+ if Ada_Version >= Ada_2012 and then Is_Disp_Req then
declare
Enclosing_Formal : Entity_Id;
Target_Formal : Entity_Id;
@@ -2659,7 +2695,7 @@ package body Sem_Ch9 is
Ref_Id : Entity_Id;
-- This is the entity of the task or task type, and is the entity used
-- for cross-reference purposes (it differs from Spec_Id in the case of
- -- a single task, since Spec_Id is set to the task type)
+ -- a single task, since Spec_Id is set to the task type).
begin
Tasking_Used := True;
@@ -3304,6 +3340,11 @@ package body Sem_Ch9 is
("dispatching operation of limited or synchronized " &
"interface required (RM 9.7.2(3))!", Error_Node);
end if;
+
+ elsif Nkind (Trigger) = N_Explicit_Dereference then
+ Error_Msg_N
+ ("entry call or dispatching primitive of interface required ",
+ Trigger);
end if;
end if;
end Check_Triggering_Statement;
diff --git a/gcc/ada/sem_dim.adb b/gcc/ada/sem_dim.adb
index 9b9de0a102b..0e46efae949 100644
--- a/gcc/ada/sem_dim.adb
+++ b/gcc/ada/sem_dim.adb
@@ -1634,7 +1634,7 @@ package body Sem_Dim is
-- the call was aborted due to a previous error.
if No (Actual) then
- Cascaded_Error;
+ Check_Error_Detected;
return;
end if;
diff --git a/gcc/ada/sem_elab.adb b/gcc/ada/sem_elab.adb
index 34aa69169d1..6d88c966e1f 100644
--- a/gcc/ada/sem_elab.adb
+++ b/gcc/ada/sem_elab.adb
@@ -828,6 +828,7 @@ package body Sem_Elab is
-- If no alias, there is a previous error
if No (Ent) then
+ Check_Error_Detected;
return;
end if;
end loop;
diff --git a/gcc/ada/sem_eval.adb b/gcc/ada/sem_eval.adb
index f7e774308fb..cf2a922f120 100644
--- a/gcc/ada/sem_eval.adb
+++ b/gcc/ada/sem_eval.adb
@@ -1294,10 +1294,13 @@ package body Sem_Eval is
begin
-- Never known at compile time if bad type or raises constraint error
- -- or empty (latter case occurs only as a result of a previous error)
+ -- or empty (latter case occurs only as a result of a previous error).
- if No (Op)
- or else Op = Error
+ if No (Op) then
+ Check_Error_Detected;
+ return False;
+
+ elsif Op = Error
or else Etype (Op) = Any_Type
or else Raises_Constraint_Error (Op)
then
@@ -1759,21 +1762,63 @@ package body Sem_Eval is
-- Eval_Case_Expression --
--------------------------
- -- Right now we do not attempt folding of any case expressions, and the
- -- language does not require it, so the only required processing is to
- -- do the check for all expressions appearing in the case expression.
+ -- A conditional expression is static if all its conditions and dependent
+ -- expressions are static.
procedure Eval_Case_Expression (N : Node_Id) is
- Alt : Node_Id;
+ Alt : Node_Id;
+ Choice : Node_Id;
+ Is_Static : Boolean;
+ Result : Node_Id;
+ Val : Uint;
begin
- Check_Non_Static_Context (Expression (N));
+ Result := Empty;
+ Is_Static := True;
+
+ if Is_Static_Expression (Expression (N)) then
+ Val := Expr_Value (Expression (N));
+
+ else
+ Check_Non_Static_Context (Expression (N));
+ Is_Static := False;
+ end if;
Alt := First (Alternatives (N));
- while Present (Alt) loop
- Check_Non_Static_Context (Expression (Alt));
+
+ Search : while Present (Alt) loop
+ if not Is_Static
+ or else not Is_Static_Expression (Expression (Alt))
+ then
+ Check_Non_Static_Context (Expression (Alt));
+ Is_Static := False;
+
+ else
+ Choice := First (Discrete_Choices (Alt));
+ while Present (Choice) loop
+ if Nkind (Choice) = N_Others_Choice then
+ Result := Expression (Alt);
+ exit Search;
+
+ elsif Expr_Value (Choice) = Val then
+ Result := Expression (Alt);
+ exit Search;
+
+ else
+ Next (Choice);
+ end if;
+ end loop;
+ end if;
+
Next (Alt);
- end loop;
+ end loop Search;
+
+ if Is_Static then
+ Rewrite (N, Relocate_Node (Result));
+
+ else
+ Set_Is_Static_Expression (N, False);
+ end if;
end Eval_Case_Expression;
------------------------
@@ -3820,7 +3865,6 @@ package body Sem_Eval is
function Expr_Value_R (N : Node_Id) return Ureal is
Kind : constant Node_Kind := Nkind (N);
Ent : Entity_Id;
- Expr : Node_Id;
begin
if Kind = N_Real_Literal then
@@ -3834,25 +3878,6 @@ package body Sem_Eval is
elsif Kind = N_Integer_Literal then
return UR_From_Uint (Expr_Value (N));
- -- Strange case of VAX literals, which are at this stage transformed
- -- into Vax_Type!x_To_y(IEEE_Literal). See Expand_N_Real_Literal in
- -- Exp_Vfpt for further details.
-
- elsif Vax_Float (Etype (N))
- and then Nkind (N) = N_Unchecked_Type_Conversion
- then
- Expr := Expression (N);
-
- if Nkind (Expr) = N_Function_Call
- and then Present (Parameter_Associations (Expr))
- then
- Expr := First (Parameter_Associations (Expr));
-
- if Nkind (Expr) = N_Real_Literal then
- return Realval (Expr);
- end if;
- end if;
-
-- Peculiar VMS case, if we have xxx'Null_Parameter, return 0.0
elsif Kind = N_Attribute_Reference
diff --git a/gcc/ada/sem_intr.adb b/gcc/ada/sem_intr.adb
index f650be9c579..93eb4924735 100644
--- a/gcc/ada/sem_intr.adb
+++ b/gcc/ada/sem_intr.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2011, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -271,7 +271,9 @@ package body Sem_Intr is
-- Return if previous error in declaration, otherwise get T2 type
if No (Next_Formal (First_Formal (E))) then
+ Check_Error_Detected;
return;
+
else
T2 := Etype (Next_Formal (First_Formal (E)));
end if;
diff --git a/gcc/ada/sem_prag.adb b/gcc/ada/sem_prag.adb
index 369376ad555..ed9af8f11bf 100644
--- a/gcc/ada/sem_prag.adb
+++ b/gcc/ada/sem_prag.adb
@@ -2121,7 +2121,8 @@ package body Sem_Prag is
(Get_Pragma_Arg (Arg2), Standard_String);
end if;
- -- Record if pragma is disabled
+ -- For a pragma in the extended main source unit, record enabled
+ -- status in SCO (note: there is never any SCO for an instance).
if Check_Enabled (Pname) then
Set_SCO_Pragma_Enabled (Loc);
@@ -5058,7 +5059,8 @@ package body Sem_Prag is
-- If previous error, avoid cascaded errors
- Applies := True;
+ Check_Error_Detected;
+ Applies := True;
Effective := True;
else
@@ -5703,18 +5705,6 @@ package body Sem_Prag is
("argument of pragma% is not valid check name", Arg1);
end if;
- -- Special processing for overflow check case
-
- if C = All_Checks or else C = Overflow_Check then
- if Suppress_Case then
- Scope_Suppress.Overflow_Checks_General := Suppressed;
- Scope_Suppress.Overflow_Checks_Assertions := Suppressed;
- else
- Scope_Suppress.Overflow_Checks_General := Checked;
- Scope_Suppress.Overflow_Checks_Assertions := Checked;
- end if;
- end if;
-
if Arg_Count = 1 then
-- Make an entry in the local scope suppress table. This is the
@@ -11284,6 +11274,135 @@ package body Sem_Prag is
Set_Standard_Fpt_Formats;
end Long_Float;
+ --------------------
+ -- Loop_Assertion --
+ --------------------
+
+ -- pragma Loop_Assertion
+ -- ( [Invariant =>] boolean_Expression );
+ -- | ( [[Invariant =>] boolean_Expression ,]
+ -- Variant =>
+ -- ( TERMINATION_VARIANT {, TERMINATION_VARIANT ) );
+
+ -- TERMINATION_VARIANT ::= CHANGE_MODIFIER => discrete_EXPRESSION
+
+ -- CHANGE_MODIFIER ::= Increasing | Decreasing
+
+ when Pragma_Loop_Assertion => Loop_Assertion : declare
+ procedure Check_Variant (Arg : Node_Id);
+ -- Verify the legality of a variant
+
+ -------------------
+ -- Check_Variant --
+ -------------------
+
+ procedure Check_Variant (Arg : Node_Id) is
+ Expr : constant Node_Id := Expression (Arg);
+
+ begin
+ -- Variants appear in aggregate form
+
+ if Nkind (Expr) = N_Aggregate then
+ declare
+ Comp : Node_Id;
+ Extra : Node_Id;
+ Modif : Node_Id;
+
+ begin
+ Comp := First (Component_Associations (Expr));
+ while Present (Comp) loop
+ Modif := First (Choices (Comp));
+ Extra := Next (Modif);
+
+ Check_Arg_Is_One_Of
+ (Modif, Name_Decreasing, Name_Increasing);
+
+ if Present (Extra) then
+ Error_Pragma_Arg
+ ("only one modifier allowed in argument", Expr);
+ end if;
+
+ Preanalyze_And_Resolve
+ (Expression (Comp), Any_Discrete);
+
+ Next (Comp);
+ end loop;
+ end;
+ else
+ Error_Pragma_Arg
+ ("expression on variant must be an aggregate", Expr);
+ end if;
+ end Check_Variant;
+
+ -- Local variables
+
+ Stmt : Node_Id;
+
+ -- Start of processing for Loop_Assertion
+
+ begin
+ GNAT_Pragma;
+ S14_Pragma;
+
+ -- Completely ignore if disabled
+
+ if Check_Disabled (Pname) then
+ Rewrite (N, Make_Null_Statement (Loc));
+ Analyze (N);
+ return;
+ end if;
+
+ -- Verify that the pragma appears inside a loop
+
+ Stmt := N;
+ while Present (Stmt) and then Nkind (Stmt) /= N_Loop_Statement loop
+ Stmt := Parent (Stmt);
+ end loop;
+
+ if No (Stmt) then
+ Error_Pragma ("pragma % must appear inside a loop");
+ end if;
+
+ Check_At_Least_N_Arguments (1);
+ Check_At_Most_N_Arguments (2);
+
+ -- Process the first argument
+
+ if Chars (Arg1) = Name_Variant then
+ Check_Variant (Arg1);
+
+ elsif Chars (Arg1) = No_Name
+ or else Chars (Arg1) = Name_Invariant
+ then
+ Preanalyze_And_Resolve (Expression (Arg1), Any_Boolean);
+
+ else
+ Error_Pragma_Arg ("argument not allowed in pragma %", Arg1);
+ end if;
+
+ -- Process the second argument
+
+ if Present (Arg2) then
+ if Chars (Arg2) = Name_Variant then
+ if Chars (Arg1) = Name_Variant then
+ Error_Pragma ("only one variant allowed in pragma %");
+ else
+ Check_Variant (Arg2);
+ end if;
+
+ elsif Chars (Arg2) = Name_Invariant then
+ if Chars (Arg1) = Name_Variant then
+ Error_Pragma_Arg ("invariant must precede variant", Arg2);
+ else
+ Error_Pragma ("only one invariant allowed in pragma %");
+ end if;
+
+ else
+ Error_Pragma_Arg ("argument not allowed in pragma %", Arg2);
+ end if;
+ end if;
+ end Loop_Assertion;
+
-----------------------
-- Machine_Attribute --
-----------------------
@@ -11878,10 +11997,11 @@ package body Sem_Prag is
-- pragma Overflow_Checks
-- ([General => ] MODE [, [Assertions => ] MODE]);
- -- MODE := SUPPRESSED | CHECKED | MINIMIZED | ELIMINATED
+ -- MODE := STRICT | MINIMIZED | ELIMINATED
-- Note: ELIMINATED is allowed only if Long_Long_Integer'Size is 64
- -- since System.Bignums makes this assumption.
+ -- since System.Bignums makes this assumption. This is true of nearly
+ -- all (all?) targets.
when Pragma_Overflow_Checks => Overflow_Checks : declare
function Get_Check_Mode
@@ -11905,19 +12025,8 @@ package body Sem_Prag is
Check_Optional_Identifier (Arg, Name);
Check_Arg_Is_Identifier (Argx);
- -- Do not suppress overflow checks for formal verification.
- -- Instead, require that a check is inserted so that formal
- -- verification can detect wraparound errors.
-
- if Chars (Argx) = Name_Suppressed then
- if Alfa_Mode then
- return Checked;
- else
- return Suppressed;
- end if;
-
- elsif Chars (Argx) = Name_Checked then
- return Checked;
+ if Chars (Argx) = Name_Strict then
+ return Strict;
elsif Chars (Argx) = Name_Minimized then
return Minimized;
@@ -14366,7 +14475,6 @@ package body Sem_Prag is
Assoc : constant Node_Id := Arg1;
Type_Id : constant Node_Id := Get_Pragma_Arg (Assoc);
Typ : Entity_Id;
- Discr : Entity_Id;
Tdef : Node_Id;
Clist : Node_Id;
Vpart : Node_Id;
@@ -14418,20 +14526,12 @@ package body Sem_Prag is
-- types and give an error, but in fact the standard does allow
-- Unchecked_Union on limited types, so this check was removed.
+ -- Similarly, GNAT used to require that all discriminants have
+ -- default values, but this is not mandated by the RM.
+
-- Proceed with basic error checks completed
else
- Discr := First_Discriminant (Typ);
- while Present (Discr) loop
- if No (Discriminant_Default_Value (Discr)) then
- Error_Msg_N
- ("unchecked union discriminant must have default value",
- Discr);
- end if;
-
- Next_Discriminant (Discr);
- end loop;
-
Tdef := Type_Definition (Declaration_Node (Typ));
Clist := Component_List (Tdef);
@@ -15428,6 +15528,7 @@ package body Sem_Prag is
Pragma_Lock_Free => -1,
Pragma_Locking_Policy => -1,
Pragma_Long_Float => -1,
+ Pragma_Loop_Assertion => -1,
Pragma_Machine_Attribute => -1,
Pragma_Main => -1,
Pragma_Main_Storage => -1,
diff --git a/gcc/ada/sem_res.adb b/gcc/ada/sem_res.adb
index defe37f3d4c..64199fa2cf6 100644
--- a/gcc/ada/sem_res.adb
+++ b/gcc/ada/sem_res.adb
@@ -334,25 +334,11 @@ package body Sem_Res is
begin
if Suppress = All_Checks then
declare
- Svg : constant Suppress_Record := Scope_Suppress;
+ Sva : constant Suppress_Array := Scope_Suppress.Suppress;
begin
- Scope_Suppress := Suppress_All;
+ Scope_Suppress.Suppress := (others => True);
Analyze_And_Resolve (N, Typ);
- Scope_Suppress := Svg;
- end;
-
- elsif Suppress = Overflow_Check then
- declare
- Svg : constant Overflow_Check_Type :=
- Scope_Suppress.Overflow_Checks_General;
- Sva : constant Overflow_Check_Type :=
- Scope_Suppress.Overflow_Checks_Assertions;
- begin
- Scope_Suppress.Overflow_Checks_General := Suppressed;
- Scope_Suppress.Overflow_Checks_Assertions := Suppressed;
- Analyze_And_Resolve (N, Typ);
- Scope_Suppress.Overflow_Checks_General := Svg;
- Scope_Suppress.Overflow_Checks_Assertions := Sva;
+ Scope_Suppress.Suppress := Sva;
end;
else
@@ -388,25 +374,11 @@ package body Sem_Res is
begin
if Suppress = All_Checks then
declare
- Svg : constant Suppress_Record := Scope_Suppress;
+ Sva : constant Suppress_Array := Scope_Suppress.Suppress;
begin
- Scope_Suppress := Suppress_All;
+ Scope_Suppress.Suppress := (others => True);
Analyze_And_Resolve (N);
- Scope_Suppress := Svg;
- end;
-
- elsif Suppress = Overflow_Check then
- declare
- Svg : constant Overflow_Check_Type :=
- Scope_Suppress.Overflow_Checks_General;
- Sva : constant Overflow_Check_Type :=
- Scope_Suppress.Overflow_Checks_Assertions;
- begin
- Scope_Suppress.Overflow_Checks_General := Suppressed;
- Scope_Suppress.Overflow_Checks_Assertions := Suppressed;
- Analyze_And_Resolve (N);
- Scope_Suppress.Overflow_Checks_General := Svg;
- Scope_Suppress.Overflow_Checks_Assertions := Sva;
+ Scope_Suppress.Suppress := Sva;
end;
else
@@ -1379,6 +1351,13 @@ package body Sem_Res is
if Nkind (Name (N)) = N_Expanded_Name then
Pack := Entity (Prefix (Name (N)));
+ -- If this is a package renaming, get renamed entity, which will be
+ -- the scope of the operands if operaton is type-correct.
+
+ if Present (Renamed_Entity (Pack)) then
+ Pack := Renamed_Entity (Pack);
+ end if;
+
-- If the entity being called is defined in the given package, it is
-- a renaming of a predefined operator, and known to be legal.
@@ -1683,11 +1662,26 @@ package body Sem_Res is
Full_Analysis := False;
Expander_Mode_Save_And_Set (False);
- -- We suppress all checks for this analysis, since the checks will
- -- be applied properly, and in the right location, when the default
- -- expression is reanalyzed and reexpanded later on.
+ -- Normally, we suppress all checks for this preanalysis. There is no
+ -- point in processing them now, since they will be applied properly
+ -- and in the proper location when the default expressions reanalyzed
+ -- and reexpanded later on. We will also have more information at that
+ -- point for possible suppression of individual checks.
- Analyze_And_Resolve (N, T, Suppress => All_Checks);
+ -- However, in Alfa mode, most expansion is suppressed, and this
+ -- later reanalysis and reexpansion may not occur. Alfa mode does
+ -- require the setting of checking flags for proof purposes, so we
+ -- do the Alfa preanalysis without suppressing checks.
+
+ -- This special handling for Alfa mode is required for example in the
+ -- case of Ada 2012 constructs such as quantified expressions, which are
+ -- expanded in two separate steps.
+
+ if Alfa_Mode then
+ Analyze_And_Resolve (N, T);
+ else
+ Analyze_And_Resolve (N, T, Suppress => All_Checks);
+ end if;
Expander_Mode_Restore;
Full_Analysis := Save_Full_Analysis;
@@ -2928,11 +2922,11 @@ package body Sem_Res is
begin
if Suppress = All_Checks then
declare
- Svg : constant Suppress_Record := Scope_Suppress;
+ Sva : constant Suppress_Array := Scope_Suppress.Suppress;
begin
- Scope_Suppress := Suppress_All;
+ Scope_Suppress.Suppress := (others => True);
Resolve (N, Typ);
- Scope_Suppress := Svg;
+ Scope_Suppress.Suppress := Sva;
end;
else
@@ -5941,16 +5935,6 @@ package body Sem_Res is
Set_Etype (N, Typ);
Eval_Case_Expression (N);
-
- -- If we still have a case expression, and overflow checks are enabled
- -- in MINIMIZED or ELIMINATED modes, then set Do_Overflow_Check to
- -- ensure that we handle overflow for dependent expressions.
-
- if Nkind (N) = N_Case_Expression
- and then Overflow_Check_Mode (Typ) in Minimized_Or_Eliminated
- then
- Set_Do_Overflow_Check (N);
- end if;
end Resolve_Case_Expression;
-------------------------------
@@ -7197,16 +7181,6 @@ package body Sem_Res is
Set_Etype (N, Typ);
Eval_If_Expression (N);
-
- -- If we still have a if expression, and overflow checks are enabled in
- -- MINIMIZED or ELIMINATED modes, then set Do_Overflow_Check to ensure
- -- that we handle overflow for dependent expressions.
-
- if Nkind (N) = N_If_Expression
- and then Overflow_Check_Mode (Typ) in Minimized_Or_Eliminated
- then
- Set_Do_Overflow_Check (N);
- end if;
end Resolve_If_Expression;
-------------------------------
diff --git a/gcc/ada/sem_type.adb b/gcc/ada/sem_type.adb
index 0c46536e961..41d9a62a9d5 100644
--- a/gcc/ada/sem_type.adb
+++ b/gcc/ada/sem_type.adb
@@ -906,9 +906,10 @@ package body Sem_Type is
-- covers an object T2 that implements a direct derivation of T1.
-- Note: test for presence of E is defense against previous error.
- if Present (E)
- and then Present (Interfaces (E))
- then
+ if No (E) then
+ Check_Error_Detected;
+
+ elsif Present (Interfaces (E)) then
Elmt := First_Elmt (Interfaces (E));
while Present (Elmt) loop
if Is_Ancestor (Etype (T1), Node (Elmt)) then
diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb
index 690e30fe5f4..8fa7c3747a3 100644
--- a/gcc/ada/sem_util.adb
+++ b/gcc/ada/sem_util.adb
@@ -5398,6 +5398,17 @@ package body Sem_Util is
N_Package_Specification);
end Has_Declarations;
+ -------------------
+ -- Has_Denormals --
+ -------------------
+
+ function Has_Denormals (E : Entity_Id) return Boolean is
+ begin
+ return Is_Floating_Point_Type (E)
+ and then Denorm_On_Target
+ and then not Vax_Float (E);
+ end Has_Denormals;
+
-------------------------------------------
-- Has_Discriminant_Dependent_Constraint --
-------------------------------------------
@@ -6076,6 +6087,17 @@ package body Sem_Util is
end if;
end Has_Private_Component;
+ ----------------------
+ -- Has_Signed_Zeros --
+ ----------------------
+
+ function Has_Signed_Zeros (E : Entity_Id) return Boolean is
+ begin
+ return Is_Floating_Point_Type (E)
+ and then Signed_Zeros_On_Target
+ and then not Vax_Float (E);
+ end Has_Signed_Zeros;
+
-----------------------------
-- Has_Static_Array_Bounds --
-----------------------------
diff --git a/gcc/ada/sem_util.ads b/gcc/ada/sem_util.ads
index bf6486d464f..b4ce100cb98 100644
--- a/gcc/ada/sem_util.ads
+++ b/gcc/ada/sem_util.ads
@@ -674,6 +674,10 @@ package Sem_Util is
function Has_Declarations (N : Node_Id) return Boolean;
-- Determines if the node can have declarations
+ function Has_Denormals (E : Entity_Id) return Boolean;
+ -- Determines if the floating-point type E supports denormal numbers.
+ -- Returns False if E is not a floating-point type.
+
function Has_Discriminant_Dependent_Constraint
(Comp : Entity_Id) return Boolean;
-- Returns True if and only if Comp has a constrained subtype that depends
@@ -708,6 +712,10 @@ package Sem_Util is
-- Check if a type has a (sub)component of a private type that has not
-- yet received a full declaration.
+ function Has_Signed_Zeros (E : Entity_Id) return Boolean;
+ -- Determines if the floating-point type E supports signed zeros.
+ -- Returns False if E is not a floating-point type.
+
function Has_Static_Array_Bounds (Typ : Node_Id) return Boolean;
-- Return whether an array type has static bounds
diff --git a/gcc/ada/sem_warn.adb b/gcc/ada/sem_warn.adb
index 34bc4582cd8..53ad6312daa 100644
--- a/gcc/ada/sem_warn.adb
+++ b/gcc/ada/sem_warn.adb
@@ -619,6 +619,7 @@ package body Sem_Warn is
if No (Entity (Ident))
or else Ekind (Entity (Ident)) /= E_Loop
then
+ Check_Error_Detected;
return;
end if;
@@ -3317,7 +3318,7 @@ package body Sem_Warn is
or else
Denotes_Same_Prefix (Act1, Act2))
then
- -- Exclude generic types and guard against previous errors.
+ -- Exclude generic types and guard against previous errors
if Error_Posted (N)
or else No (Etype (Act1))
diff --git a/gcc/ada/snames.ads-tmpl b/gcc/ada/snames.ads-tmpl
index 0fd39c34ef8..efd340f01d6 100644
--- a/gcc/ada/snames.ads-tmpl
+++ b/gcc/ada/snames.ads-tmpl
@@ -405,6 +405,7 @@ package Snames is
Name_License : constant Name_Id := N + $; -- GNAT
Name_Locking_Policy : constant Name_Id := N + $;
Name_Long_Float : constant Name_Id := N + $; -- VMS
+ Name_Loop_Assertion : constant Name_Id := N + $; -- GNAT
Name_No_Run_Time : constant Name_Id := N + $; -- GNAT
Name_No_Strict_Aliasing : constant Name_Id := N + $; -- GNAT
Name_Normalize_Scalars : constant Name_Id := N + $;
@@ -664,12 +665,12 @@ package Snames is
Name_By_Protected_Procedure : constant Name_Id := N + $;
Name_Casing : constant Name_Id := N + $;
Name_Check_All : constant Name_Id := N + $;
- Name_Checked : constant Name_Id := N + $;
Name_Code : constant Name_Id := N + $;
Name_Component : constant Name_Id := N + $;
Name_Component_Size_4 : constant Name_Id := N + $;
Name_Copy : constant Name_Id := N + $;
Name_D_Float : constant Name_Id := N + $;
+ Name_Decreasing : constant Name_Id := N + $;
Name_Descriptor : constant Name_Id := N + $;
Name_Disable : constant Name_Id := N + $;
Name_Dot_Replacement : constant Name_Id := N + $;
@@ -689,6 +690,7 @@ package Snames is
Name_GPL : constant Name_Id := N + $;
Name_IEEE_Float : constant Name_Id := N + $;
Name_Ignore : constant Name_Id := N + $;
+ Name_Increasing : constant Name_Id := N + $;
Name_Info : constant Name_Id := N + $;
Name_Internal : constant Name_Id := N + $;
Name_Link_Name : constant Name_Id := N + $;
@@ -736,6 +738,7 @@ package Snames is
Name_State : constant Name_Id := N + $;
Name_Static : constant Name_Id := N + $;
Name_Stack_Size : constant Name_Id := N + $;
+ Name_Strict : constant Name_Id := N + $;
Name_Subunit_File_Name : constant Name_Id := N + $;
Name_Suppressed : constant Name_Id := N + $;
Name_Task_Stack_Size_Default : constant Name_Id := N + $;
@@ -750,6 +753,7 @@ package Snames is
Name_Unrestricted : constant Name_Id := N + $;
Name_Uppercase : constant Name_Id := N + $;
Name_User : constant Name_Id := N + $;
+ Name_Variant : constant Name_Id := N + $;
Name_VAX_Float : constant Name_Id := N + $;
Name_VMS : constant Name_Id := N + $;
Name_Vtable_Ptr : constant Name_Id := N + $;
@@ -767,6 +771,10 @@ package Snames is
-- The entries marked VMS are recognized only in OpenVMS implementations
-- of GNAT, and are treated as illegal in all other contexts.
+ -- The entries marked HiLite are attributes that are defined by Hi-Lite
+ -- and implemented in GNAT operating under formal verification mode. The
+ -- entries are treated as illegal in all other contexts.
+
First_Attribute_Name : constant Name_Id := N + $;
Name_Abort_Signal : constant Name_Id := N + $; -- GNAT
Name_Access : constant Name_Id := N + $;
@@ -828,6 +836,7 @@ package Snames is
Name_Leading_Part : constant Name_Id := N + $;
Name_Length : constant Name_Id := N + $;
Name_Lock_Free : constant Name_Id := N + $; -- GNAT
+ Name_Loop_Entry : constant Name_Id := N + $; -- HiLite
Name_Machine_Emax : constant Name_Id := N + $;
Name_Machine_Emin : constant Name_Id := N + $;
Name_Machine_Mantissa : constant Name_Id := N + $;
@@ -1438,6 +1447,7 @@ package Snames is
Attribute_Leading_Part,
Attribute_Length,
Attribute_Lock_Free,
+ Attribute_Loop_Entry,
Attribute_Machine_Emax,
Attribute_Machine_Emin,
Attribute_Machine_Mantissa,
@@ -1675,6 +1685,7 @@ package Snames is
Pragma_License,
Pragma_Locking_Policy,
Pragma_Long_Float,
+ Pragma_Loop_Assertion,
Pragma_No_Run_Time,
Pragma_No_Strict_Aliasing,
Pragma_Normalize_Scalars,
diff --git a/gcc/ada/stylesw.adb b/gcc/ada/stylesw.adb
index cce2b8ff745..886043bd8c3 100644
--- a/gcc/ada/stylesw.adb
+++ b/gcc/ada/stylesw.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2011, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
diff --git a/gcc/ada/switch-c.adb b/gcc/ada/switch-c.adb
index 2a96c06d11a..e7d517e794e 100644
--- a/gcc/ada/switch-c.adb
+++ b/gcc/ada/switch-c.adb
@@ -97,11 +97,8 @@ package body Switch.C is
function Get_Overflow_Mode (C : Character) return Overflow_Check_Type is
begin
case C is
- when '0' =>
- return Suppressed;
-
when '1' =>
- return Checked;
+ return Strict;
when '2' =>
return Minimized;
@@ -801,12 +798,13 @@ package body Switch.C is
when 'o' =>
Ptr := Ptr + 1;
+ Suppress_Options.Suppress (Overflow_Check) := False;
-- Case of no digits after the -gnato
- if Ptr > Max or else Switch_Chars (Ptr) not in '0' .. '3' then
- Suppress_Options.Overflow_Checks_General := Checked;
- Suppress_Options.Overflow_Checks_Assertions := Checked;
+ if Ptr > Max or else Switch_Chars (Ptr) not in '1' .. '3' then
+ Suppress_Options.Overflow_Checks_General := Strict;
+ Suppress_Options.Overflow_Checks_Assertions := Strict;
-- At least one digit after the -gnato
@@ -821,7 +819,7 @@ package body Switch.C is
-- be the same as general mode.
if Ptr > Max
- or else Switch_Chars (Ptr) not in '0' .. '3'
+ or else Switch_Chars (Ptr) not in '1' .. '3'
then
Suppress_Options.Overflow_Checks_Assertions :=
Suppress_Options.Overflow_Checks_General;
@@ -869,9 +867,6 @@ package body Switch.C is
end if;
end loop;
- Suppress_Options.Overflow_Checks_General := Suppressed;
- Suppress_Options.Overflow_Checks_Assertions := Suppressed;
-
Validity_Checks_On := False;
Opt.Suppress_Checks := True;
end if;
diff --git a/gcc/ada/sysdep.c b/gcc/ada/sysdep.c
index ee31840d8d6..1eec8b96f88 100644
--- a/gcc/ada/sysdep.c
+++ b/gcc/ada/sysdep.c
@@ -44,6 +44,10 @@
#include "vxWorks.h"
#endif
+#ifdef __ANDROID__
+#undef linux
+#endif
+
#ifdef IN_RTS
#define POSIX
#include "tconfig.h"
@@ -923,3 +927,48 @@ __gnat_is_file_not_found_error (int errno_val) {
return 0;
}
}
+
+#ifdef __ANDROID__
+
+/* Provide extern symbols for sig* as needed by the tasking run-time, instead
+ of static inline functions. */
+
+#include <signal.h>
+
+int
+_sigismember (sigset_t *set, int signum)
+{
+ return sigismember (set, signum);
+}
+
+int
+_sigaddset (sigset_t *set, int signum)
+{
+ return sigaddset (set, signum);
+}
+
+int
+_sigdelset (sigset_t *set, int signum)
+{
+ return sigdelset (set, signum);
+}
+
+int
+_sigemptyset (sigset_t *set)
+{
+ return sigemptyset (set);
+}
+
+int
+_sigfillset (sigset_t *set)
+{
+ return sigfillset (set);
+}
+
+#include <unistd.h>
+int
+_getpagesize (void)
+{
+ return getpagesize ();
+}
+#endif
diff --git a/gcc/ada/terminals.c b/gcc/ada/terminals.c
index ca672c48b37..36b97a6f1a1 100644
--- a/gcc/ada/terminals.c
+++ b/gcc/ada/terminals.c
@@ -31,7 +31,8 @@
/* First all usupported platforms. Add stubs for exported routines. */
-#if defined (VMS) || defined (__vxworks) || defined (__Lynx__)
+#if defined (VMS) || defined (__vxworks) || defined (__Lynx__) || \
+ defined (__ANDROID__)
void * __gnat_new_tty (void) { return (void*)0; }
char * __gnat_tty_name (void* t) { return (char*)0; }
diff --git a/gcc/ada/types.ads b/gcc/ada/types.ads
index 277bfd55146..861c0bcc1c8 100644
--- a/gcc/ada/types.ads
+++ b/gcc/ada/types.ads
@@ -703,43 +703,39 @@ package Types is
-- 4. Add a new Do_xxx_Check flag to Sinfo (if required)
-- 5. Add appropriate checks for the new test
- -- The following provides precise details on the mode used to check
- -- intermediate overflows in expressions for signed integer arithmetic.
+ -- The following provides precise details on the mode used to generate
+ -- code for intermediate overflows in expressions for signed integer
+ -- arithmetic (and how to generate overflow checks if enabled). Note
+ -- that this only affects handling of intermediate results. The final
+ -- result must always fit within the target range, and if overflow
+ -- checking is enabled, the check on the final result is against this
+ -- target range.
type Overflow_Check_Type is (
Not_Set,
-- Dummy value used during initialization process to show that the
-- corresponding value has not yet been initialized.
- Suppressed,
- -- Overflow checking is suppressed. If an arithmetic operation creates
- -- an overflow, no exception is raised, and the program is erroneous.
-
- Checked,
- -- All operations, including all intermediate operations are checked.
- -- If the result of any arithmetic operation gives a result outside the
- -- range of the base type, then a Constraint_Error exception is raised.
+ Strict,
+ -- Operations are done in the base type of the subexpression. If
+ -- overflow checks are enabled, then the check is against the range
+ -- of this base type.
Minimized,
- -- Where appropriate, arithmetic operations are performed with an
- -- extended range, using Long_Long_Integer if necessary. As long as the
- -- result fits in this extended range, then no exception is raised and
- -- computation continues with the extended result. The final value of an
- -- expression must fit in the base type of the whole expression. If an
- -- intermediate result is outside the range of Long_Long_Integer then a
- -- Constraint_Error exception is raised.
+ -- Where appropriate, intermediate arithmetic operations are performed
+ -- with an extended range, using Long_Long_Integer if necessary. If
+ -- overflow checking is enabled, then the check is against the range
+ -- of Long_Long_Integer.
Eliminated);
-- In this mode arbitrary precision arithmetic is used as needed to
-- ensure that it is impossible for intermediate arithmetic to cause an
- -- overflow. Again the final value of an expression must fit in the base
- -- type of the whole expression.
+ -- overflow. In this mode, intermediate expressions are not affected by
+ -- the overflow checking mode, since overflows are eliminated.
subtype Minimized_Or_Eliminated is
Overflow_Check_Type range Minimized .. Eliminated;
- subtype Suppressed_Or_Checked is
- Overflow_Check_Type range Suppressed .. Checked;
- -- Define subtypes so that clients don't need to know ordering. Note that
+ -- Define subtype so that clients don't need to know ordering. Note that
-- Overflow_Check_Type is not marked as an ordered enumeration type.
-- The following structure captures the state of check suppression or
@@ -747,24 +743,19 @@ package Types is
type Suppress_Record is record
Suppress : Suppress_Array;
- -- Indicates suppression status of each possible check. Note: there
- -- is an entry for Overflow_Check in this array, but it is never used.
- -- Instead we use the more detailed information in the two components
- -- that follow this one (Overflow_Checks_General/Assertions).
+ -- Indicates suppression status of each possible check
Overflow_Checks_General : Overflow_Check_Type;
- -- This field indicates the mode of overflow checking to be applied to
- -- general expressions outside assertions.
+ -- This field indicates the mode for handling code generation and
+ -- overflow checking (if enabled) for intermediate expression values.
+ -- This applies to general expressions outside assertions.
Overflow_Checks_Assertions : Overflow_Check_Type;
- -- This field indicates the mode of overflow checking to be applied to
- -- any expression occuring inside assertions.
+ -- This field indicates the mode for handling code generation and
+ -- overflow checking (if enabled) for intermediate expression values.
+ -- This applies to any expression occuring inside assertions.
end record;
- Suppress_All : constant Suppress_Record :=
- ((others => True), Suppressed, Suppressed);
- -- Constant used to initialize Suppress_Record value to all suppressed.
-
-----------------------------------
-- Global Exception Declarations --
-----------------------------------
diff --git a/gcc/ada/uintp.adb b/gcc/ada/uintp.adb
index a98bd9f376b..0761f2df70b 100644
--- a/gcc/ada/uintp.adb
+++ b/gcc/ada/uintp.adb
@@ -1216,6 +1216,15 @@ package body Uintp is
-- [ CALCULATE Q (hat) ] (step D3 in the algorithm)
+ -- Note: this version of step D3 is from the original published
+ -- algorithm, which is known to have a bug causing overflows.
+ -- See: http://www-cs-faculty.stanford.edu/~uno/err2-2e.ps.gz.
+ -- In this code we are safe since our representation of double
+ -- length numbers allows an expanded range.
+
+ -- We don't have a proof of this claim, but the only cases we
+ -- have found that show the bug in step D3 work fine here.
+
Tmp_Int := Dividend (J) * Base + Dividend (J + 1);
-- Initial guess
@@ -1230,7 +1239,7 @@ package body Uintp is
while Divisor_Dig2 * Q_Guess >
(Tmp_Int - Q_Guess * Divisor_Dig1) * Base +
- Dividend (J + 2)
+ Dividend (J + 2)
loop
Q_Guess := Q_Guess - 1;
end loop;
diff --git a/gcc/ada/uintp.ads b/gcc/ada/uintp.ads
index b730f44879a..dcf85a07f37 100644
--- a/gcc/ada/uintp.ads
+++ b/gcc/ada/uintp.ads
@@ -407,7 +407,7 @@ private
Base : constant Int := 2 ** Base_Bits;
- -- Values in the range -(Base+1) .. Max_Direct are encoded directly as
+ -- Values in the range -(Base-1) .. Max_Direct are encoded directly as
-- Uint values by adding a bias value. The value of Max_Direct is chosen
-- so that a directly represented number always fits in two digits when
-- represented in base format.
diff --git a/gcc/ada/vms_data.ads b/gcc/ada/vms_data.ads
index 8c1c1eb73ec..e4b04b78351 100644
--- a/gcc/ada/vms_data.ads
+++ b/gcc/ada/vms_data.ads
@@ -2117,12 +2117,11 @@ package VMS_Data is
-- range 0-3, it sets the overflow checking mode for all expressions,
-- including those outside and within assertions. The meaning of nnn is:
--
- -- 0 suppress overflow checks (SUPPRESSED)
- -- 1 all intermediate overflows checked (CHECKED)
+ -- 1 all intermediate computations done using base type (STRICT)
-- 2 minimize intermediate overflows (MINIMIZED)
-- 3 eliminate intermediate overflows (ELIMINATED)
--
- -- Otherwise nn can be two digits, both 0-3, and in this case the first
+ -- Otherwise nn can be two digits, both 1-3, and in this case the first
-- digit sets the mode (using the above code) for expressions outside an
-- assertion, and the second digit sets the mode for expressions within
-- an assertion.
diff --git a/gcc/ada/xoscons.adb b/gcc/ada/xoscons.adb
index ec452c34406..74b76c9455b 100644
--- a/gcc/ada/xoscons.adb
+++ b/gcc/ada/xoscons.adb
@@ -33,26 +33,29 @@
-- The generated files are UNIT_NAME.ads and UNIT_NAME.h
-with Ada.Characters.Handling; use Ada.Characters.Handling;
-with Ada.Command_Line; use Ada.Command_Line;
-with Ada.Exceptions; use Ada.Exceptions;
-with Ada.Strings.Fixed; use Ada.Strings.Fixed;
-with Ada.Text_IO; use Ada.Text_IO;
-with Ada.Streams.Stream_IO; use Ada.Streams.Stream_IO;
+with Ada.Characters.Handling; use Ada.Characters.Handling;
+with Ada.Command_Line; use Ada.Command_Line;
+with Ada.Exceptions; use Ada.Exceptions;
+with Ada.Streams.Stream_IO; use Ada.Streams.Stream_IO;
+with Ada.Strings.Fixed; use Ada.Strings.Fixed;
+with Ada.Strings.Maps; use Ada.Strings.Maps;
+with Ada.Strings.Maps.Constants; use Ada.Strings.Maps.Constants;
+with Ada.Text_IO; use Ada.Text_IO;
pragma Warnings (Off);
-- System.Unsigned_Types is an internal GNAT unit
with System.Unsigned_Types; use System.Unsigned_Types;
pragma Warnings (On);
+with GNAT.String_Split; use GNAT.String_Split;
with GNAT.Table;
with XUtil; use XUtil;
procedure XOSCons is
- use ASCII;
use Ada.Strings;
+ use ASCII;
Unit_Name : constant String := Argument (1);
Tmpl_Name : constant String := Unit_Name & "-tmplt";
@@ -73,6 +76,9 @@ procedure XOSCons is
Abs_Value : Long_Unsigned := 0;
end record;
+ function ">" (V1, V2 : Int_Value_Type) return Boolean;
+ function "<" (V1, V2 : Int_Value_Type) return Boolean;
+
type Asm_Info_Kind is
(CND, -- Named number (decimal)
CNU, -- Named number (decimal, unsigned)
@@ -129,6 +135,10 @@ procedure XOSCons is
type Language is (Lang_Ada, Lang_C);
+ function Parse_Int (S : String; K : Asm_Int_Kind) return Int_Value_Type;
+ -- Parse a decimal number, preceded by an optional '$' or '#' character,
+ -- and return its value.
+
procedure Output_Info
(Lang : Language;
OFile : Sfile;
@@ -145,6 +155,30 @@ procedure XOSCons is
-- If Count is positive, return a string of Count spaces, else return an
-- empty string.
+ ---------
+ -- ">" --
+ ---------
+
+ function ">" (V1, V2 : Int_Value_Type) return Boolean is
+ P1 : Boolean renames V1.Positive;
+ P2 : Boolean renames V2.Positive;
+ A1 : Long_Unsigned renames V1.Abs_Value;
+ A2 : Long_Unsigned renames V2.Abs_Value;
+ begin
+ return (P1 and then not P2)
+ or else (P1 and then P2 and then A1 > A2)
+ or else (not P1 and then not P2 and then A1 < A2);
+ end ">";
+
+ ---------
+ -- "<" --
+ ---------
+
+ function "<" (V1, V2 : Int_Value_Type) return Boolean is
+ begin
+ return not (V1 > V2) and then not (V1 = V2);
+ end "<";
+
----------------------------
-- Contains_Template_Name --
----------------------------
@@ -283,10 +317,6 @@ procedure XOSCons is
procedure Find_Colon (Index : in out Integer);
-- Increment Index until the next colon in Line
- function Parse_Int (S : String; K : Asm_Int_Kind) return Int_Value_Type;
- -- Parse a decimal number, preceded by an optional '$' or '#' character,
- -- and return its value.
-
-----------------
-- Field_Alloc --
-----------------
@@ -308,53 +338,6 @@ procedure XOSCons is
end loop;
end Find_Colon;
- ---------------
- -- Parse_Int --
- ---------------
-
- function Parse_Int
- (S : String;
- K : Asm_Int_Kind) return Int_Value_Type
- is
- First : Integer := S'First;
- Result : Int_Value_Type;
-
- begin
- -- On some platforms, immediate integer values are prefixed with
- -- a $ or # character in assembly output.
-
- if S (First) = '$' or else S (First) = '#' then
- First := First + 1;
- end if;
-
- if S (First) = '-' then
- Result.Positive := False;
- First := First + 1;
- else
- Result.Positive := True;
- end if;
-
- Result.Abs_Value := Long_Unsigned'Value (S (First .. S'Last));
-
- if not Result.Positive and then K = CNU then
-
- -- Negative value, but unsigned expected: take 2's complement
- -- reciprocical value.
-
- Result.Abs_Value := ((not Result.Abs_Value) + 1)
- and
- (Shift_Left (1, Size_Of_Unsigned_Int) - 1);
- Result.Positive := True;
- end if;
-
- return Result;
-
- exception
- when others =>
- Put_Line (Standard_Error, "can't parse decimal value: " & S);
- raise;
- end Parse_Int;
-
-- Start of processing for Parse_Asm_Line
begin
@@ -448,6 +431,153 @@ procedure XOSCons is
(Standard_Error, "exception raised: " & Exception_Information (E));
end Parse_Asm_Line;
+ ----------------
+ -- Parse_Cond --
+ ----------------
+
+ procedure Parse_Cond
+ (If_Line : String;
+ Cond : Boolean;
+ Tmpl_File : Ada.Text_IO.File_Type;
+ Ada_Ofile, C_Ofile : Sfile;
+ Current_Line : in out Integer)
+ is
+ function Get_Value (Name : String) return Int_Value_Type;
+ -- Returns the value of the variable Name
+
+ ---------------
+ -- Get_Value --
+ ---------------
+
+ function Get_Value (Name : String) return Int_Value_Type is
+ begin
+ if Is_Subset (To_Set (Name), Decimal_Digit_Set) then
+ return Parse_Int (Name, CND);
+
+ else
+ for K in 1 .. Asm_Infos.Last loop
+ if Asm_Infos.Table (K).Constant_Name /= null then
+ if Name = Asm_Infos.Table (K).Constant_Name.all then
+ return Asm_Infos.Table (K).Int_Value;
+ end if;
+ end if;
+ end loop;
+
+ -- Not found returns 0
+
+ return (True, 0);
+ end if;
+ end Get_Value;
+
+ -- Local variables
+
+ Sline : Slice_Set;
+ Line : String (1 .. 256);
+ Last : Integer;
+ Value1 : Int_Value_Type;
+ Value2 : Int_Value_Type;
+ Res : Boolean;
+
+ -- Start of processing for Parse_Cond
+
+ begin
+ Create (Sline, If_Line, " ");
+
+ if Slice_Count (Sline) /= 4 then
+ Put_Line (Standard_Error, "can't parse " & If_Line);
+ end if;
+
+ Value1 := Get_Value (Slice (Sline, 2));
+ Value2 := Get_Value (Slice (Sline, 4));
+
+ if Slice (Sline, 3) = ">" then
+ Res := Cond and (Value1 > Value2);
+
+ elsif Slice (Sline, 3) = "<" then
+ Res := Cond and (Value1 < Value2);
+
+ elsif Slice (Sline, 3) = "=" then
+ Res := Cond and (Value1 = Value2);
+
+ elsif Slice (Sline, 3) = "/=" then
+ Res := Cond and (Value1 /= Value2);
+
+ else
+ -- No other operator can be used
+
+ Put_Line (Standard_Error, "unknown operator in " & If_Line);
+ Res := False;
+ end if;
+
+ Current_Line := Current_Line + 1;
+
+ loop
+ Get_Line (Tmpl_File, Line, Last);
+ Current_Line := Current_Line + 1;
+ exit when Line (1 .. Last) = "@END_IF";
+
+ if Line (1 .. 4) = "@IF " then
+ Parse_Cond
+ (Line (1 .. Last), Res,
+ Tmpl_File, Ada_Ofile, C_Ofile, Current_Line);
+
+ elsif Line (1 .. Last) = "@ELSE" then
+ Res := Cond and not Res;
+
+ elsif Res then
+ Put_Line (Ada_OFile, Line (1 .. Last));
+ Put_Line (C_OFile, Line (1 .. Last));
+ end if;
+ end loop;
+ end Parse_Cond;
+
+ ---------------
+ -- Parse_Int --
+ ---------------
+
+ function Parse_Int
+ (S : String;
+ K : Asm_Int_Kind) return Int_Value_Type
+ is
+ First : Integer := S'First;
+ Result : Int_Value_Type;
+
+ begin
+ -- On some platforms, immediate integer values are prefixed with
+ -- a $ or # character in assembly output.
+
+ if S (First) = '$' or else S (First) = '#' then
+ First := First + 1;
+ end if;
+
+ if S (First) = '-' then
+ Result.Positive := False;
+ First := First + 1;
+ else
+ Result.Positive := True;
+ end if;
+
+ Result.Abs_Value := Long_Unsigned'Value (S (First .. S'Last));
+
+ if not Result.Positive and then K = CNU then
+
+ -- Negative value, but unsigned expected: take 2's complement
+ -- reciprocical value.
+
+ Result.Abs_Value := ((not Result.Abs_Value) + 1)
+ and
+ (Shift_Left (1, Size_Of_Unsigned_Int) - 1);
+ Result.Positive := True;
+ end if;
+
+ return Result;
+
+ exception
+ when others =>
+ Put_Line (Standard_Error, "can't parse decimal value: " & S);
+ raise;
+ end Parse_Int;
+
------------
-- Spaces --
------------
@@ -540,6 +670,12 @@ begin
if Line (1 .. Last) = "*/" then
Put_Line (C_OFile, Line (1 .. Last));
In_Comment := False;
+
+ elsif Last > 4 and then Line (1 .. 4) = "@IF " then
+ Parse_Cond
+ (Line (1 .. Last), True,
+ Tmpl_File, Ada_Ofile, C_Ofile, Current_Line);
+
else
Put_Line (Ada_OFile, Line (1 .. Last));
Put_Line (C_OFile, Line (1 .. Last));
@@ -550,8 +686,11 @@ begin
In_Comment := True;
elsif Asm_Infos.Table (Current_Info).Line_Number = Current_Line then
- Output_Info (Lang_Ada, Ada_OFile, Current_Info);
- Output_Info (Lang_C, C_OFile, Current_Info);
+ if Fixed.Index (Line, "/*NOGEN*/") = 0 then
+ Output_Info (Lang_Ada, Ada_OFile, Current_Info);
+ Output_Info (Lang_C, C_OFile, Current_Info);
+ end if;
+
Current_Info := Current_Info + 1;
end if;
diff --git a/gcc/ada/xutil.adb b/gcc/ada/xutil.adb
index fbc755c0981..cdf0b05cc28 100644
--- a/gcc/ada/xutil.adb
+++ b/gcc/ada/xutil.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2008, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -25,8 +25,8 @@
package body XUtil is
- use Ada.Strings.Unbounded;
use Ada.Streams.Stream_IO;
+ use Ada.Strings.Unbounded;
--------------
-- New_Line --
diff --git a/gcc/ada/xutil.ads b/gcc/ada/xutil.ads
index b99ca0db002..e8f67a9fc62 100644
--- a/gcc/ada/xutil.ads
+++ b/gcc/ada/xutil.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 1992-2008, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h
index 94ad6372d28..5cd62b3d640 100644
--- a/gcc/cfgloop.h
+++ b/gcc/cfgloop.h
@@ -714,6 +714,7 @@ extern void doloop_optimize_loops (void);
extern void move_loop_invariants (void);
extern bool finite_loop_p (struct loop *);
extern void scale_loop_profile (struct loop *loop, int scale, int iteration_bound);
+extern VEC (basic_block, heap) * get_loop_hot_path (const struct loop *loop);
/* Returns the outermost loop of the loop nest that contains LOOP.*/
static inline struct loop *
diff --git a/gcc/cfgloopanal.c b/gcc/cfgloopanal.c
index c3cf3edf9b9..ba7c2626635 100644
--- a/gcc/cfgloopanal.c
+++ b/gcc/cfgloopanal.c
@@ -483,3 +483,36 @@ single_likely_exit (struct loop *loop)
VEC_free (edge, heap, exits);
return found;
}
+
+
+/* Gets basic blocks of a LOOP. Header is the 0-th block, rest is in dfs
+ order against direction of edges from latch. Specially, if
+ header != latch, latch is the 1-st block. */
+
+VEC (basic_block, heap) *
+get_loop_hot_path (const struct loop *loop)
+{
+ basic_block bb = loop->header;
+ VEC (basic_block, heap) *path = NULL;
+ bitmap visited = BITMAP_ALLOC (NULL);
+
+ while (true)
+ {
+ edge_iterator ei;
+ edge e;
+ edge best = NULL;
+
+ VEC_safe_push (basic_block, heap, path, bb);
+ bitmap_set_bit (visited, bb->index);
+ FOR_EACH_EDGE (e, ei, bb->succs)
+ if ((!best || e->probability > best->probability)
+ && !loop_exit_edge_p (loop, e)
+ && !bitmap_bit_p (visited, e->dest->index))
+ best = e;
+ if (!best || best->dest == loop->header)
+ break;
+ bb = best->dest;
+ }
+ BITMAP_FREE (visited);
+ return path;
+}
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index 01e3bf526af..556eaff29d4 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -132,6 +132,144 @@ static GTY(()) struct cgraph_edge *free_edges;
/* Did procss_same_body_aliases run? */
bool same_body_aliases_done;
+/* Map a cgraph_node to cgraph_function_version_info using this htab.
+ The cgraph_function_version_info has a THIS_NODE field that is the
+ corresponding cgraph_node.. */
+
+static htab_t GTY((param_is (struct cgraph_function_version_info *)))
+ cgraph_fnver_htab = NULL;
+
+/* Hash function for cgraph_fnver_htab. */
+static hashval_t
+cgraph_fnver_htab_hash (const void *ptr)
+{
+ int uid = ((const struct cgraph_function_version_info *)ptr)->this_node->uid;
+ return (hashval_t)(uid);
+}
+
+/* eq function for cgraph_fnver_htab. */
+static int
+cgraph_fnver_htab_eq (const void *p1, const void *p2)
+{
+ const struct cgraph_function_version_info *n1
+ = (const struct cgraph_function_version_info *)p1;
+ const struct cgraph_function_version_info *n2
+ = (const struct cgraph_function_version_info *)p2;
+
+ return n1->this_node->uid == n2->this_node->uid;
+}
+
+/* Mark as GC root all allocated nodes. */
+static GTY(()) struct cgraph_function_version_info *
+ version_info_node = NULL;
+
+/* Get the cgraph_function_version_info node corresponding to node. */
+struct cgraph_function_version_info *
+get_cgraph_node_version (struct cgraph_node *node)
+{
+ struct cgraph_function_version_info *ret;
+ struct cgraph_function_version_info key;
+ key.this_node = node;
+
+ if (cgraph_fnver_htab == NULL)
+ return NULL;
+
+ ret = (struct cgraph_function_version_info *)
+ htab_find (cgraph_fnver_htab, &key);
+
+ return ret;
+}
+
+/* Insert a new cgraph_function_version_info node into cgraph_fnver_htab
+ corresponding to cgraph_node NODE. */
+struct cgraph_function_version_info *
+insert_new_cgraph_node_version (struct cgraph_node *node)
+{
+ void **slot;
+
+ version_info_node = NULL;
+ version_info_node = ggc_alloc_cleared_cgraph_function_version_info ();
+ version_info_node->this_node = node;
+
+ if (cgraph_fnver_htab == NULL)
+ cgraph_fnver_htab = htab_create_ggc (2, cgraph_fnver_htab_hash,
+ cgraph_fnver_htab_eq, NULL);
+
+ slot = htab_find_slot (cgraph_fnver_htab, version_info_node, INSERT);
+ gcc_assert (slot != NULL);
+ *slot = version_info_node;
+ return version_info_node;
+}
+
+/* Remove the cgraph_function_version_info and cgraph_node for DECL. This
+ DECL is a duplicate declaration. */
+void
+delete_function_version (tree decl)
+{
+ struct cgraph_node *decl_node = cgraph_get_create_node (decl);
+ struct cgraph_function_version_info *decl_v = NULL;
+
+ if (decl_node == NULL)
+ return;
+
+ decl_v = get_cgraph_node_version (decl_node);
+
+ if (decl_v == NULL)
+ return;
+
+ if (decl_v->prev != NULL)
+ decl_v->prev->next = decl_v->next;
+
+ if (decl_v->next != NULL)
+ decl_v->next->prev = decl_v->prev;
+
+ if (cgraph_fnver_htab != NULL)
+ htab_remove_elt (cgraph_fnver_htab, decl_v);
+
+ cgraph_remove_node (decl_node);
+}
+
+/* Record that DECL1 and DECL2 are semantically identical function
+ versions. */
+void
+record_function_versions (tree decl1, tree decl2)
+{
+ struct cgraph_node *decl1_node = cgraph_get_create_node (decl1);
+ struct cgraph_node *decl2_node = cgraph_get_create_node (decl2);
+ struct cgraph_function_version_info *decl1_v = NULL;
+ struct cgraph_function_version_info *decl2_v = NULL;
+ struct cgraph_function_version_info *before;
+ struct cgraph_function_version_info *after;
+
+ gcc_assert (decl1_node != NULL && decl2_node != NULL);
+ decl1_v = get_cgraph_node_version (decl1_node);
+ decl2_v = get_cgraph_node_version (decl2_node);
+
+ if (decl1_v != NULL && decl2_v != NULL)
+ return;
+
+ if (decl1_v == NULL)
+ decl1_v = insert_new_cgraph_node_version (decl1_node);
+
+ if (decl2_v == NULL)
+ decl2_v = insert_new_cgraph_node_version (decl2_node);
+
+ /* Chain decl2_v and decl1_v. All semantically identical versions
+ will be chained together. */
+
+ before = decl1_v;
+ after = decl2_v;
+
+ while (before->next != NULL)
+ before = before->next;
+
+ while (after->prev != NULL)
+ after= after->prev;
+
+ before->next = after;
+ after->prev = before;
+}
+
/* Macros to access the next item in the list of free cgraph nodes and
edges. */
#define NEXT_FREE_NODE(NODE) cgraph ((NODE)->symbol.next)
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index f276512df31..25c1f33eb57 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -280,6 +280,8 @@ struct GTY(()) cgraph_node {
/* ?? We should be able to remove this. We have enough bits in
cgraph to calculate it. */
unsigned tm_clone : 1;
+ /* True if this decl is a dispatcher for function versions. */
+ unsigned dispatcher_function : 1;
};
DEF_VEC_P(symtab_node);
@@ -292,6 +294,47 @@ DEF_VEC_P(cgraph_node_ptr);
DEF_VEC_ALLOC_P(cgraph_node_ptr,heap);
DEF_VEC_ALLOC_P(cgraph_node_ptr,gc);
+/* Function Multiversioning info. */
+struct GTY(()) cgraph_function_version_info {
+ /* The cgraph_node for which the function version info is stored. */
+ struct cgraph_node *this_node;
+ /* Chains all the semantically identical function versions. The
+ first function in this chain is the version_info node of the
+ default function. */
+ struct cgraph_function_version_info *prev;
+ /* If this version node corresponds to a dispatcher for function
+ versions, this points to the version info node of the default
+ function, the first node in the chain. */
+ struct cgraph_function_version_info *next;
+ /* If this node corresponds to a function version, this points
+ to the dispatcher function decl, which is the function that must
+ be called to execute the right function version at run-time.
+
+ If this cgraph node is a dispatcher (if dispatcher_function is
+ true, in the cgraph_node struct) for function versions, this
+ points to resolver function, which holds the function body of the
+ dispatcher. The dispatcher decl is an alias to the resolver
+ function decl. */
+ tree dispatcher_resolver;
+};
+
+/* Get the cgraph_function_version_info node corresponding to node. */
+struct cgraph_function_version_info *
+ get_cgraph_node_version (struct cgraph_node *node);
+
+/* Insert a new cgraph_function_version_info node into cgraph_fnver_htab
+ corresponding to cgraph_node NODE. */
+struct cgraph_function_version_info *
+ insert_new_cgraph_node_version (struct cgraph_node *node);
+
+/* Record that DECL1 and DECL2 are semantically identical function
+ versions. */
+void record_function_versions (tree decl1, tree decl2);
+
+/* Remove the cgraph_function_version_info and cgraph_node for DECL. This
+ DECL is a duplicate declaration. */
+void delete_function_version (tree decl);
+
/* A cgraph node set is a collection of cgraph nodes. A cgraph node
can appear in multiple sets. */
struct cgraph_node_set_def
@@ -638,6 +681,9 @@ void init_cgraph (void);
bool cgraph_process_new_functions (void);
void cgraph_process_same_body_aliases (void);
void fixup_same_cpp_alias_visibility (symtab_node node, symtab_node target, tree alias);
+/* Initialize datastructures so DECL is a function in lowered gimple form.
+ IN_SSA is true if the gimple is in SSA. */
+basic_block init_lowered_empty_function (tree decl, bool in_ssa);
/* In cgraphclones.c */
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 230125c4a69..bf1326bbb88 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -630,6 +630,21 @@ cgraph_analyze_function (struct cgraph_node *node)
cgraph_create_edge (node, cgraph_get_node (node->thunk.alias),
NULL, 0, CGRAPH_FREQ_BASE);
}
+ else if (node->dispatcher_function)
+ {
+ /* Generate the dispatcher body of multi-versioned functions. */
+ struct cgraph_function_version_info *dispatcher_version_info
+ = get_cgraph_node_version (node);
+ if (dispatcher_version_info != NULL
+ && (dispatcher_version_info->dispatcher_resolver
+ == NULL_TREE))
+ {
+ tree resolver = NULL_TREE;
+ gcc_assert (targetm.generate_version_dispatcher_body);
+ resolver = targetm.generate_version_dispatcher_body (node);
+ gcc_assert (resolver != NULL_TREE);
+ }
+ }
else
{
push_cfun (DECL_STRUCT_FUNCTION (decl));
@@ -938,7 +953,8 @@ cgraph_analyze_functions (void)
See gcc.c-torture/compile/20011119-1.c */
if (!DECL_STRUCT_FUNCTION (decl)
&& (!cnode->alias || !cnode->thunk.alias)
- && !cnode->thunk.thunk_p)
+ && !cnode->thunk.thunk_p
+ && !cnode->dispatcher_function)
{
cgraph_reset_node (cnode);
cnode->local.redefined_extern_inline = true;
@@ -1219,13 +1235,13 @@ mark_functions_to_output (void)
}
/* DECL is FUNCTION_DECL. Initialize datastructures so DECL is a function
- in lowered gimple form.
+ in lowered gimple form. IN_SSA is true if the gimple is in SSA.
Set current_function_decl and cfun to newly constructed empty function body.
return basic block in the function body. */
-static basic_block
-init_lowered_empty_function (tree decl)
+basic_block
+init_lowered_empty_function (tree decl, bool in_ssa)
{
basic_block bb;
@@ -1233,9 +1249,14 @@ init_lowered_empty_function (tree decl)
allocate_struct_function (decl, false);
gimple_register_cfg_hooks ();
init_empty_tree_cfg ();
- init_tree_ssa (cfun);
- init_ssa_operands (cfun);
- cfun->gimple_df->in_ssa_p = true;
+
+ if (in_ssa)
+ {
+ init_tree_ssa (cfun);
+ init_ssa_operands (cfun);
+ cfun->gimple_df->in_ssa_p = true;
+ }
+
DECL_INITIAL (decl) = make_node (BLOCK);
DECL_SAVED_TREE (decl) = error_mark_node;
@@ -1442,7 +1463,7 @@ assemble_thunk (struct cgraph_node *node)
else
resdecl = DECL_RESULT (thunk_fndecl);
- bb = then_bb = else_bb = return_bb = init_lowered_empty_function (thunk_fndecl);
+ bb = then_bb = else_bb = return_bb = init_lowered_empty_function (thunk_fndecl, true);
bsi = gsi_start_bb (bb);
diff --git a/gcc/config/epiphany/epiphany.c b/gcc/config/epiphany/epiphany.c
index 65bb1c8ee88..4279a146e04 100644
--- a/gcc/config/epiphany/epiphany.c
+++ b/gcc/config/epiphany/epiphany.c
@@ -1,6 +1,6 @@
/* Subroutines used for code generation on the EPIPHANY cpu.
Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
- 2004, 2005, 2006, 2007, 2009, 2010, 2011 Free Software Foundation, Inc.
+ 2004, 2005, 2006, 2007, 2009-2012 Free Software Foundation, Inc.
Contributed by Embecosm on behalf of Adapteva, Inc.
This file is part of GCC.
@@ -729,7 +729,7 @@ epiphany_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
If ADDR is not a valid address, its cost is irrelevant. */
static int
-epiphany_address_cost (rtx addr, enum machine_mode mode ATTRIBUTE_UNUSED,
+epiphany_address_cost (rtx addr, enum machine_mode mode,
addr_space_t as ATTRIBUTE_UNUSED, bool speed)
{
rtx reg;
@@ -761,19 +761,28 @@ epiphany_address_cost (rtx addr, enum machine_mode mode ATTRIBUTE_UNUSED,
}
if (!satisfies_constraint_Rgs (reg))
return 1;
- /* ??? We don't know the mode of the memory access. We are going to assume
- SImode, unless lack of offset alignment indicates a smaller access. */
+ /* The offset range available for short instructions depends on the mode
+ of the memory access. */
/* First, make sure we have a valid integer. */
if (!satisfies_constraint_L (off))
return 1;
i = INTVAL (off);
- if ((i & 1) == 0)
- i >>= 1;
- if ((i & 1) == 0)
- i >>= 1;
- if (i < -7 || i > 7)
- return 1;
- return 0;
+ switch (GET_MODE_SIZE (mode))
+ {
+ default:
+ case 4:
+ if (i & 1)
+ return 1;
+ i >>= 1;
+ /* Fall through. */
+ case 2:
+ if (i & 1)
+ return 1;
+ i >>= 1;
+ /* Fall through. */
+ case 1:
+ return i < -7 || i > 7;
+ }
}
/* Compute the cost of moving data between registers and memory.
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index 96971aeb628..0d643b139d6 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -167,8 +167,13 @@ extern bool ix86_secondary_memory_needed (enum reg_class, enum reg_class,
enum machine_mode, int);
extern bool ix86_cannot_change_mode_class (enum machine_mode,
enum machine_mode, enum reg_class);
+
extern int ix86_mode_needed (int, rtx);
-extern void emit_i387_cw_initialization (int);
+extern int ix86_mode_after (int, int, rtx);
+extern int ix86_mode_entry (int);
+extern int ix86_mode_exit (int);
+extern void ix86_emit_mode_set (int, int);
+
extern void x86_order_regs_for_local_alloc (void);
extern void x86_function_profiler (FILE *, int);
extern void x86_emit_floatuns (rtx [2]);
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 2066b894be9..ec40dd59bb1 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -62,6 +62,8 @@ along with GCC; see the file COPYING3. If not see
#include "opts.h"
#include "diagnostic.h"
#include "dumpfile.h"
+#include "tree-pass.h"
+#include "tree-flow.h"
enum upper_128bits_state
{
@@ -70,48 +72,16 @@ enum upper_128bits_state
used
};
-typedef struct block_info_def
-{
- /* State of the upper 128bits of AVX registers at exit. */
- enum upper_128bits_state state;
- /* TRUE if state of the upper 128bits of AVX registers is unchanged
- in this block. */
- bool unchanged;
- /* TRUE if block has been processed. */
- bool processed;
- /* TRUE if block has been scanned. */
- bool scanned;
- /* Previous state of the upper 128bits of AVX registers at entry. */
- enum upper_128bits_state prev;
-} *block_info;
-
-#define BLOCK_INFO(B) ((block_info) (B)->aux)
-
-enum call_avx256_state
-{
- /* Callee returns 256bit AVX register. */
- callee_return_avx256 = -1,
- /* Callee returns and passes 256bit AVX register. */
- callee_return_pass_avx256,
- /* Callee passes 256bit AVX register. */
- callee_pass_avx256,
- /* Callee doesn't return nor passe 256bit AVX register, or no
- 256bit AVX register in function return. */
- call_no_avx256,
- /* vzeroupper intrinsic. */
- vzeroupper_intrinsic
-};
-
/* Check if a 256bit AVX register is referenced in stores. */
static void
check_avx256_stores (rtx dest, const_rtx set, void *data)
{
- if ((REG_P (dest)
- && VALID_AVX256_REG_MODE (GET_MODE (dest)))
+ if (((REG_P (dest) || MEM_P(dest))
+ && VALID_AVX256_REG_OR_OI_MODE (GET_MODE (dest)))
|| (GET_CODE (set) == SET
- && REG_P (SET_SRC (set))
- && VALID_AVX256_REG_MODE (GET_MODE (SET_SRC (set)))))
+ && (REG_P (SET_SRC (set)) || MEM_P (SET_SRC (set)))
+ && VALID_AVX256_REG_OR_OI_MODE (GET_MODE (SET_SRC (set)))))
{
enum upper_128bits_state *state
= (enum upper_128bits_state *) data;
@@ -119,377 +89,6 @@ check_avx256_stores (rtx dest, const_rtx set, void *data)
}
}
-/* Helper function for move_or_delete_vzeroupper_1. Look for vzeroupper
- in basic block BB. Delete it if upper 128bit AVX registers are
- unused. If it isn't deleted, move it to just before a jump insn.
-
- STATE is state of the upper 128bits of AVX registers at entry. */
-
-static void
-move_or_delete_vzeroupper_2 (basic_block bb,
- enum upper_128bits_state state)
-{
- rtx insn, bb_end;
- rtx vzeroupper_insn = NULL_RTX;
- rtx pat;
- int avx256;
- bool unchanged;
-
- if (BLOCK_INFO (bb)->unchanged)
- {
- if (dump_file)
- fprintf (dump_file, " [bb %i] unchanged: upper 128bits: %d\n",
- bb->index, state);
-
- BLOCK_INFO (bb)->state = state;
- return;
- }
-
- if (BLOCK_INFO (bb)->scanned && BLOCK_INFO (bb)->prev == state)
- {
- if (dump_file)
- fprintf (dump_file, " [bb %i] scanned: upper 128bits: %d\n",
- bb->index, BLOCK_INFO (bb)->state);
- return;
- }
-
- BLOCK_INFO (bb)->prev = state;
-
- if (dump_file)
- fprintf (dump_file, " [bb %i] entry: upper 128bits: %d\n",
- bb->index, state);
-
- unchanged = true;
-
- /* BB_END changes when it is deleted. */
- bb_end = BB_END (bb);
- insn = BB_HEAD (bb);
- while (insn != bb_end)
- {
- insn = NEXT_INSN (insn);
-
- if (!NONDEBUG_INSN_P (insn))
- continue;
-
- /* Move vzeroupper before jump/call. */
- if (JUMP_P (insn) || CALL_P (insn))
- {
- if (!vzeroupper_insn)
- continue;
-
- if (PREV_INSN (insn) != vzeroupper_insn)
- {
- if (dump_file)
- {
- fprintf (dump_file, "Move vzeroupper after:\n");
- print_rtl_single (dump_file, PREV_INSN (insn));
- fprintf (dump_file, "before:\n");
- print_rtl_single (dump_file, insn);
- }
- reorder_insns_nobb (vzeroupper_insn, vzeroupper_insn,
- PREV_INSN (insn));
- }
- vzeroupper_insn = NULL_RTX;
- continue;
- }
-
- pat = PATTERN (insn);
-
- /* Check insn for vzeroupper intrinsic. */
- if (GET_CODE (pat) == UNSPEC_VOLATILE
- && XINT (pat, 1) == UNSPECV_VZEROUPPER)
- {
- if (dump_file)
- {
- /* Found vzeroupper intrinsic. */
- fprintf (dump_file, "Found vzeroupper:\n");
- print_rtl_single (dump_file, insn);
- }
- }
- else
- {
- /* Check insn for vzeroall intrinsic. */
- if (GET_CODE (pat) == PARALLEL
- && GET_CODE (XVECEXP (pat, 0, 0)) == UNSPEC_VOLATILE
- && XINT (XVECEXP (pat, 0, 0), 1) == UNSPECV_VZEROALL)
- {
- state = unused;
- unchanged = false;
-
- /* Delete pending vzeroupper insertion. */
- if (vzeroupper_insn)
- {
- delete_insn (vzeroupper_insn);
- vzeroupper_insn = NULL_RTX;
- }
- }
- else if (state != used)
- {
- note_stores (pat, check_avx256_stores, &state);
- if (state == used)
- unchanged = false;
- }
- continue;
- }
-
- /* Process vzeroupper intrinsic. */
- avx256 = INTVAL (XVECEXP (pat, 0, 0));
-
- if (state == unused)
- {
- /* Since the upper 128bits are cleared, callee must not pass
- 256bit AVX register. We only need to check if callee
- returns 256bit AVX register. */
- if (avx256 == callee_return_avx256)
- {
- state = used;
- unchanged = false;
- }
-
- /* Remove unnecessary vzeroupper since upper 128bits are
- cleared. */
- if (dump_file)
- {
- fprintf (dump_file, "Delete redundant vzeroupper:\n");
- print_rtl_single (dump_file, insn);
- }
- delete_insn (insn);
- }
- else
- {
- /* Set state to UNUSED if callee doesn't return 256bit AVX
- register. */
- if (avx256 != callee_return_pass_avx256)
- state = unused;
-
- if (avx256 == callee_return_pass_avx256
- || avx256 == callee_pass_avx256)
- {
- /* Must remove vzeroupper since callee passes in 256bit
- AVX register. */
- if (dump_file)
- {
- fprintf (dump_file, "Delete callee pass vzeroupper:\n");
- print_rtl_single (dump_file, insn);
- }
- delete_insn (insn);
- }
- else
- {
- vzeroupper_insn = insn;
- unchanged = false;
- }
- }
- }
-
- BLOCK_INFO (bb)->state = state;
- BLOCK_INFO (bb)->unchanged = unchanged;
- BLOCK_INFO (bb)->scanned = true;
-
- if (dump_file)
- fprintf (dump_file, " [bb %i] exit: %s: upper 128bits: %d\n",
- bb->index, unchanged ? "unchanged" : "changed",
- state);
-}
-
-/* Helper function for move_or_delete_vzeroupper. Process vzeroupper
- in BLOCK and check its predecessor blocks. Treat UNKNOWN state
- as USED if UNKNOWN_IS_UNUSED is true. Return TRUE if the exit
- state is changed. */
-
-static bool
-move_or_delete_vzeroupper_1 (basic_block block, bool unknown_is_unused)
-{
- edge e;
- edge_iterator ei;
- enum upper_128bits_state state, old_state, new_state;
- bool seen_unknown;
-
- if (dump_file)
- fprintf (dump_file, " Process [bb %i]: status: %d\n",
- block->index, BLOCK_INFO (block)->processed);
-
- if (BLOCK_INFO (block)->processed)
- return false;
-
- state = unused;
-
- /* Check all predecessor edges of this block. */
- seen_unknown = false;
- FOR_EACH_EDGE (e, ei, block->preds)
- {
- if (e->src == block)
- continue;
- switch (BLOCK_INFO (e->src)->state)
- {
- case unknown:
- if (!unknown_is_unused)
- seen_unknown = true;
- case unused:
- break;
- case used:
- state = used;
- goto done;
- }
- }
-
- if (seen_unknown)
- state = unknown;
-
-done:
- old_state = BLOCK_INFO (block)->state;
- move_or_delete_vzeroupper_2 (block, state);
- new_state = BLOCK_INFO (block)->state;
-
- if (state != unknown || new_state == used)
- BLOCK_INFO (block)->processed = true;
-
- /* Need to rescan if the upper 128bits of AVX registers are changed
- to USED at exit. */
- if (new_state != old_state)
- {
- if (new_state == used)
- cfun->machine->rescan_vzeroupper_p = 1;
- return true;
- }
- else
- return false;
-}
-
-/* Go through the instruction stream looking for vzeroupper. Delete
- it if upper 128bit AVX registers are unused. If it isn't deleted,
- move it to just before a jump insn. */
-
-static void
-move_or_delete_vzeroupper (void)
-{
- edge e;
- edge_iterator ei;
- basic_block bb;
- fibheap_t worklist, pending, fibheap_swap;
- sbitmap visited, in_worklist, in_pending, sbitmap_swap;
- int *bb_order;
- int *rc_order;
- int i;
-
- /* Set up block info for each basic block. */
- alloc_aux_for_blocks (sizeof (struct block_info_def));
-
- /* Process outgoing edges of entry point. */
- if (dump_file)
- fprintf (dump_file, "Process outgoing edges of entry point\n");
-
- FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR->succs)
- {
- move_or_delete_vzeroupper_2 (e->dest,
- cfun->machine->caller_pass_avx256_p
- ? used : unused);
- BLOCK_INFO (e->dest)->processed = true;
- }
-
- /* Compute reverse completion order of depth first search of the CFG
- so that the data-flow runs faster. */
- rc_order = XNEWVEC (int, n_basic_blocks - NUM_FIXED_BLOCKS);
- bb_order = XNEWVEC (int, last_basic_block);
- pre_and_rev_post_order_compute (NULL, rc_order, false);
- for (i = 0; i < n_basic_blocks - NUM_FIXED_BLOCKS; i++)
- bb_order[rc_order[i]] = i;
- free (rc_order);
-
- worklist = fibheap_new ();
- pending = fibheap_new ();
- visited = sbitmap_alloc (last_basic_block);
- in_worklist = sbitmap_alloc (last_basic_block);
- in_pending = sbitmap_alloc (last_basic_block);
- bitmap_clear (in_worklist);
-
- /* Don't check outgoing edges of entry point. */
- bitmap_ones (in_pending);
- FOR_EACH_BB (bb)
- if (BLOCK_INFO (bb)->processed)
- bitmap_clear_bit (in_pending, bb->index);
- else
- {
- move_or_delete_vzeroupper_1 (bb, false);
- fibheap_insert (pending, bb_order[bb->index], bb);
- }
-
- if (dump_file)
- fprintf (dump_file, "Check remaining basic blocks\n");
-
- while (!fibheap_empty (pending))
- {
- fibheap_swap = pending;
- pending = worklist;
- worklist = fibheap_swap;
- sbitmap_swap = in_pending;
- in_pending = in_worklist;
- in_worklist = sbitmap_swap;
-
- bitmap_clear (visited);
-
- cfun->machine->rescan_vzeroupper_p = 0;
-
- while (!fibheap_empty (worklist))
- {
- bb = (basic_block) fibheap_extract_min (worklist);
- bitmap_clear_bit (in_worklist, bb->index);
- gcc_assert (!bitmap_bit_p (visited, bb->index));
- if (!bitmap_bit_p (visited, bb->index))
- {
- edge_iterator ei;
-
- bitmap_set_bit (visited, bb->index);
-
- if (move_or_delete_vzeroupper_1 (bb, false))
- FOR_EACH_EDGE (e, ei, bb->succs)
- {
- if (e->dest == EXIT_BLOCK_PTR
- || BLOCK_INFO (e->dest)->processed)
- continue;
-
- if (bitmap_bit_p (visited, e->dest->index))
- {
- if (!bitmap_bit_p (in_pending, e->dest->index))
- {
- /* Send E->DEST to next round. */
- bitmap_set_bit (in_pending, e->dest->index);
- fibheap_insert (pending,
- bb_order[e->dest->index],
- e->dest);
- }
- }
- else if (!bitmap_bit_p (in_worklist, e->dest->index))
- {
- /* Add E->DEST to current round. */
- bitmap_set_bit (in_worklist, e->dest->index);
- fibheap_insert (worklist, bb_order[e->dest->index],
- e->dest);
- }
- }
- }
- }
-
- if (!cfun->machine->rescan_vzeroupper_p)
- break;
- }
-
- free (bb_order);
- fibheap_delete (worklist);
- fibheap_delete (pending);
- sbitmap_free (visited);
- sbitmap_free (in_worklist);
- sbitmap_free (in_pending);
-
- if (dump_file)
- fprintf (dump_file, "Process remaining basic blocks\n");
-
- FOR_EACH_BB (bb)
- move_or_delete_vzeroupper_1 (bb, true);
-
- free_aux_for_blocks ();
-}
-
static rtx legitimize_dllimport_symbol (rtx, bool);
#ifndef CHECK_STACK_LIMIT
@@ -4123,37 +3722,6 @@ ix86_option_override_internal (bool main_args_p)
= build_target_option_node ();
}
-/* Return TRUE if VAL is passed in register with 256bit AVX modes. */
-
-static bool
-function_pass_avx256_p (const_rtx val)
-{
- if (!val)
- return false;
-
- if (REG_P (val) && VALID_AVX256_REG_MODE (GET_MODE (val)))
- return true;
-
- if (GET_CODE (val) == PARALLEL)
- {
- int i;
- rtx r;
-
- for (i = XVECLEN (val, 0) - 1; i >= 0; i--)
- {
- r = XVECEXP (val, 0, i);
- if (GET_CODE (r) == EXPR_LIST
- && XEXP (r, 0)
- && REG_P (XEXP (r, 0))
- && (GET_MODE (XEXP (r, 0)) == OImode
- || VALID_AVX256_REG_MODE (GET_MODE (XEXP (r, 0)))))
- return true;
- }
- }
-
- return false;
-}
-
/* Implement the TARGET_OPTION_OVERRIDE hook. */
static void
@@ -5076,15 +4644,6 @@ ix86_function_ok_for_sibcall (tree decl, tree exp)
if (!rtx_equal_p (a, b))
return false;
}
- else if (VOID_TYPE_P (TREE_TYPE (DECL_RESULT (cfun->decl))))
- {
- /* Disable sibcall if we need to generate vzeroupper after
- callee returns. */
- if (TARGET_VZEROUPPER
- && cfun->machine->callee_return_avx256_p
- && !cfun->machine->caller_return_avx256_p)
- return false;
- }
else if (!rtx_equal_p (a, b))
return false;
@@ -5864,45 +5423,18 @@ init_cumulative_args (CUMULATIVE_ARGS *cum, /* Argument info to initialize */
int caller)
{
struct cgraph_local_info *i;
- tree fnret_type;
memset (cum, 0, sizeof (*cum));
- /* Initialize for the current callee. */
- if (caller)
- {
- cfun->machine->callee_pass_avx256_p = false;
- cfun->machine->callee_return_avx256_p = false;
- }
-
if (fndecl)
{
i = cgraph_local_info (fndecl);
cum->call_abi = ix86_function_abi (fndecl);
- fnret_type = TREE_TYPE (TREE_TYPE (fndecl));
}
else
{
i = NULL;
cum->call_abi = ix86_function_type_abi (fntype);
- if (fntype)
- fnret_type = TREE_TYPE (fntype);
- else
- fnret_type = NULL;
- }
-
- if (TARGET_VZEROUPPER && fnret_type)
- {
- rtx fnret_value = ix86_function_value (fnret_type, fntype,
- false);
- if (function_pass_avx256_p (fnret_value))
- {
- /* The return value of this function uses 256bit AVX modes. */
- if (caller)
- cfun->machine->callee_return_avx256_p = true;
- else
- cfun->machine->caller_return_avx256_p = true;
- }
}
cum->caller = caller;
@@ -7195,15 +6727,6 @@ ix86_function_arg (cumulative_args_t cum_v, enum machine_mode omode,
else
arg = function_arg_32 (cum, mode, omode, type, bytes, words);
- if (TARGET_VZEROUPPER && function_pass_avx256_p (arg))
- {
- /* This argument uses 256bit AVX modes. */
- if (cum->caller)
- cfun->machine->callee_pass_avx256_p = true;
- else
- cfun->machine->caller_pass_avx256_p = true;
- }
-
return arg;
}
@@ -11042,17 +10565,6 @@ ix86_emit_restore_sse_regs_using_mov (HOST_WIDE_INT cfa_offset,
}
}
-/* Emit vzeroupper if needed. */
-
-void
-ix86_maybe_emit_epilogue_vzeroupper (void)
-{
- if (TARGET_VZEROUPPER
- && !TREE_THIS_VOLATILE (cfun->decl)
- && !cfun->machine->caller_return_avx256_p)
- emit_insn (gen_avx_vzeroupper (GEN_INT (call_no_avx256)));
-}
-
/* Restore function stack, frame, and registers. */
void
@@ -11354,9 +10866,6 @@ ix86_expand_epilogue (int style)
return;
}
- /* Emit vzeroupper if needed. */
- ix86_maybe_emit_epilogue_vzeroupper ();
-
if (crtl->args.pops_args && crtl->args.size)
{
rtx popc = GEN_INT (crtl->args.pops_args);
@@ -14119,7 +13628,7 @@ print_reg (rtx x, int code, FILE *file)
/* Irritatingly, AMD extended registers use different naming convention
from the normal registers: "r%d[bwd]" */
- if (REX_INT_REG_P (x))
+ if (REX_INT_REGNO_P (regno))
{
gcc_assert (TARGET_64BIT);
putc ('r', file);
@@ -15453,8 +14962,46 @@ output_387_binary_op (rtx insn, rtx *operands)
/* Return needed mode for entity in optimize_mode_switching pass. */
-int
-ix86_mode_needed (int entity, rtx insn)
+static int
+ix86_avx_u128_mode_needed (rtx insn)
+{
+ rtx pat = PATTERN (insn);
+ rtx arg;
+ enum upper_128bits_state state;
+
+ if (CALL_P (insn))
+ {
+ /* Needed mode is set to AVX_U128_CLEAN if there are
+ no 256bit modes used in function arguments. */
+ for (arg = CALL_INSN_FUNCTION_USAGE (insn); arg;
+ arg = XEXP (arg, 1))
+ {
+ if (GET_CODE (XEXP (arg, 0)) == USE)
+ {
+ rtx reg = XEXP (XEXP (arg, 0), 0);
+
+ if (reg && REG_P (reg)
+ && VALID_AVX256_REG_OR_OI_MODE (GET_MODE (reg)))
+ return AVX_U128_ANY;
+ }
+ }
+
+ return AVX_U128_CLEAN;
+ }
+
+ /* Check if a 256bit AVX register is referenced in stores. */
+ state = unused;
+ note_stores (pat, check_avx256_stores, &state);
+ if (state == used)
+ return AVX_U128_DIRTY;
+ return AVX_U128_ANY;
+}
+
+/* Return mode that i387 must be switched into
+ prior to the execution of insn. */
+
+static int
+ix86_i387_mode_needed (int entity, rtx insn)
{
enum attr_i387_cw mode;
@@ -15503,11 +15050,166 @@ ix86_mode_needed (int entity, rtx insn)
return I387_CW_ANY;
}
+/* Return mode that entity must be switched into
+ prior to the execution of insn. */
+
+int
+ix86_mode_needed (int entity, rtx insn)
+{
+ switch (entity)
+ {
+ case AVX_U128:
+ return ix86_avx_u128_mode_needed (insn);
+ case I387_TRUNC:
+ case I387_FLOOR:
+ case I387_CEIL:
+ case I387_MASK_PM:
+ return ix86_i387_mode_needed (entity, insn);
+ default:
+ gcc_unreachable ();
+ }
+ return 0;
+}
+
+/* Calculate mode of upper 128bit AVX registers after the insn. */
+
+static int
+ix86_avx_u128_mode_after (int mode, rtx insn)
+{
+ rtx pat = PATTERN (insn);
+ rtx reg = NULL;
+ int i;
+ enum upper_128bits_state state;
+
+ /* Check for CALL instruction. */
+ if (CALL_P (insn))
+ {
+ if (GET_CODE (pat) == SET || GET_CODE (pat) == CALL)
+ reg = SET_DEST (pat);
+ else if (GET_CODE (pat) == PARALLEL)
+ for (i = XVECLEN (pat, 0) - 1; i >= 0; i--)
+ {
+ rtx x = XVECEXP (pat, 0, i);
+ if (GET_CODE(x) == SET)
+ reg = SET_DEST (x);
+ }
+ /* Mode after call is set to AVX_U128_DIRTY if there are
+ 256bit modes used in the function return register. */
+ if (reg && REG_P (reg) && VALID_AVX256_REG_OR_OI_MODE (GET_MODE (reg)))
+ return AVX_U128_DIRTY;
+ else
+ return AVX_U128_CLEAN;
+ }
+
+ if (vzeroupper_operation (pat, VOIDmode)
+ || vzeroall_operation (pat, VOIDmode))
+ return AVX_U128_CLEAN;
+
+ /* Check if a 256bit AVX register is referenced in stores. */
+ state = unused;
+ note_stores (pat, check_avx256_stores, &state);
+ if (state == used)
+ return AVX_U128_DIRTY;
+
+ return mode;
+}
+
+/* Return the mode that an insn results in. */
+
+int
+ix86_mode_after (int entity, int mode, rtx insn)
+{
+ switch (entity)
+ {
+ case AVX_U128:
+ return ix86_avx_u128_mode_after (mode, insn);
+ case I387_TRUNC:
+ case I387_FLOOR:
+ case I387_CEIL:
+ case I387_MASK_PM:
+ return mode;
+ default:
+ gcc_unreachable ();
+ }
+}
+
+static int
+ix86_avx_u128_mode_entry (void)
+{
+ tree arg;
+
+ /* Entry mode is set to AVX_U128_DIRTY if there are
+ 256bit modes used in function arguments. */
+ for (arg = DECL_ARGUMENTS (current_function_decl); arg;
+ arg = TREE_CHAIN (arg))
+ {
+ rtx reg = DECL_INCOMING_RTL (arg);
+
+ if (reg && REG_P (reg) && VALID_AVX256_REG_OR_OI_MODE (GET_MODE (reg)))
+ return AVX_U128_DIRTY;
+ }
+
+ return AVX_U128_CLEAN;
+}
+
+/* Return a mode that ENTITY is assumed to be
+ switched to at function entry. */
+
+int
+ix86_mode_entry (int entity)
+{
+ switch (entity)
+ {
+ case AVX_U128:
+ return ix86_avx_u128_mode_entry ();
+ case I387_TRUNC:
+ case I387_FLOOR:
+ case I387_CEIL:
+ case I387_MASK_PM:
+ return I387_CW_ANY;
+ default:
+ gcc_unreachable ();
+ }
+}
+
+static int
+ix86_avx_u128_mode_exit (void)
+{
+ rtx reg = crtl->return_rtx;
+
+ /* Exit mode is set to AVX_U128_DIRTY if there are
+ 256bit modes used in the function return register. */
+ if (reg && REG_P (reg) && VALID_AVX256_REG_OR_OI_MODE (GET_MODE (reg)))
+ return AVX_U128_DIRTY;
+
+ return AVX_U128_CLEAN;
+}
+
+/* Return a mode that ENTITY is assumed to be
+ switched to at function exit. */
+
+int
+ix86_mode_exit (int entity)
+{
+ switch (entity)
+ {
+ case AVX_U128:
+ return ix86_avx_u128_mode_exit ();
+ case I387_TRUNC:
+ case I387_FLOOR:
+ case I387_CEIL:
+ case I387_MASK_PM:
+ return I387_CW_ANY;
+ default:
+ gcc_unreachable ();
+ }
+}
+
/* Output code to initialize control word copies used by trunc?f?i and
rounding patterns. CURRENT_MODE is set to current control word,
while NEW_MODE is set to new control word. */
-void
+static void
emit_i387_cw_initialization (int mode)
{
rtx stored_mode = assign_386_stack_local (HImode, SLOT_CW_STORED);
@@ -15594,6 +15296,30 @@ emit_i387_cw_initialization (int mode)
emit_move_insn (new_mode, reg);
}
+/* Generate one or more insns to set ENTITY to MODE. */
+
+void
+ix86_emit_mode_set (int entity, int mode)
+{
+ switch (entity)
+ {
+ case AVX_U128:
+ if (mode == AVX_U128_CLEAN)
+ emit_insn (gen_avx_vzeroupper ());
+ break;
+ case I387_TRUNC:
+ case I387_FLOOR:
+ case I387_CEIL:
+ case I387_MASK_PM:
+ if (mode != I387_CW_ANY
+ && mode != I387_CW_UNINITIALIZED)
+ emit_i387_cw_initialization (mode);
+ break;
+ default:
+ gcc_unreachable ();
+ }
+}
+
/* Output code for INSN to convert a float to a signed int. OPERANDS
are the insn operands. The output may be [HSD]Imode and the input
operand may be [SDX]Fmode. */
@@ -23602,30 +23328,6 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1,
clobbered_registers[i]));
}
- /* Add UNSPEC_CALL_NEEDS_VZEROUPPER decoration. */
- if (TARGET_VZEROUPPER)
- {
- int avx256;
- if (cfun->machine->callee_pass_avx256_p)
- {
- if (cfun->machine->callee_return_avx256_p)
- avx256 = callee_return_pass_avx256;
- else
- avx256 = callee_pass_avx256;
- }
- else if (cfun->machine->callee_return_avx256_p)
- avx256 = callee_return_avx256;
- else
- avx256 = call_no_avx256;
-
- if (reload_completed)
- emit_insn (gen_avx_vzeroupper (GEN_INT (avx256)));
- else
- vec[vec_len++] = gen_rtx_UNSPEC (VOIDmode,
- gen_rtvec (1, GEN_INT (avx256)),
- UNSPEC_CALL_NEEDS_VZEROUPPER);
- }
-
if (vec_len > 1)
call = gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (vec_len, vec));
call = emit_call_insn (call);
@@ -23635,25 +23337,6 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1,
return call;
}
-void
-ix86_split_call_vzeroupper (rtx insn, rtx vzeroupper)
-{
- rtx pat = PATTERN (insn);
- rtvec vec = XVEC (pat, 0);
- int len = GET_NUM_ELEM (vec) - 1;
-
- /* Strip off the last entry of the parallel. */
- gcc_assert (GET_CODE (RTVEC_ELT (vec, len)) == UNSPEC);
- gcc_assert (XINT (RTVEC_ELT (vec, len), 1) == UNSPEC_CALL_NEEDS_VZEROUPPER);
- if (len == 1)
- pat = RTVEC_ELT (vec, 0);
- else
- pat = gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (len, &RTVEC_ELT (vec, 0)));
-
- emit_insn (gen_avx_vzeroupper (vzeroupper));
- emit_call_insn (pat);
-}
-
/* Output the assembly for a call instruction. */
const char *
@@ -23734,6 +23417,7 @@ ix86_init_machine_status (void)
f->use_fast_prologue_epilogue_nregs = -1;
f->tls_descriptor_call_expanded_p = 0;
f->call_abi = ix86_abi;
+ f->optimize_mode_switching[AVX_U128] = TARGET_VZEROUPPER;
return f;
}
@@ -23751,9 +23435,6 @@ assign_386_stack_local (enum machine_mode mode, enum ix86_stack_slot n)
gcc_assert (n < MAX_386_STACK_LOCALS);
- /* Virtual slot is valid only before vregs are instantiated. */
- gcc_assert ((n == SLOT_VIRTUAL) == !virtuals_instantiated);
-
for (s = ix86_stack_locals; s; s = s->next)
if (s->mode == mode && s->n == n)
return validize_mem (copy_rtx (s->rtl));
@@ -23767,6 +23448,16 @@ assign_386_stack_local (enum machine_mode mode, enum ix86_stack_slot n)
ix86_stack_locals = s;
return validize_mem (s->rtl);
}
+
+static void
+ix86_instantiate_decls (void)
+{
+ struct stack_local_entry *s;
+
+ for (s = ix86_stack_locals; s; s = s->next)
+ if (s->rtl != NULL_RTX)
+ instantiate_decl_rtl (s->rtl);
+}
/* Calculate the length of the memory address in the instruction encoding.
Includes addr32 prefix, does not include the one-byte modrm, opcode,
@@ -27656,7 +27347,7 @@ static const struct builtin_description bdesc_args[] =
{ OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_zero_extendv4hiv4di2 , "__builtin_ia32_pmovzxwq256", IX86_BUILTIN_PMOVZXWQ256, UNKNOWN, (int) V4DI_FTYPE_V8HI },
{ OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_zero_extendv4siv4di2 , "__builtin_ia32_pmovzxdq256", IX86_BUILTIN_PMOVZXDQ256, UNKNOWN, (int) V4DI_FTYPE_V4SI },
{ OPTION_MASK_ISA_AVX2, CODE_FOR_vec_widen_smult_even_v8si, "__builtin_ia32_pmuldq256", IX86_BUILTIN_PMULDQ256, UNKNOWN, (int) V4DI_FTYPE_V8SI_V8SI },
- { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_umulhrswv16hi3 , "__builtin_ia32_pmulhrsw256", IX86_BUILTIN_PMULHRSW256, UNKNOWN, (int) V16HI_FTYPE_V16HI_V16HI },
+ { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_pmulhrswv16hi3 , "__builtin_ia32_pmulhrsw256", IX86_BUILTIN_PMULHRSW256, UNKNOWN, (int) V16HI_FTYPE_V16HI_V16HI },
{ OPTION_MASK_ISA_AVX2, CODE_FOR_umulv16hi3_highpart, "__builtin_ia32_pmulhuw256" , IX86_BUILTIN_PMULHUW256 , UNKNOWN, (int) V16HI_FTYPE_V16HI_V16HI },
{ OPTION_MASK_ISA_AVX2, CODE_FOR_smulv16hi3_highpart, "__builtin_ia32_pmulhw256" , IX86_BUILTIN_PMULHW256 , UNKNOWN, (int) V16HI_FTYPE_V16HI_V16HI },
{ OPTION_MASK_ISA_AVX2, CODE_FOR_mulv16hi3, "__builtin_ia32_pmullw256" , IX86_BUILTIN_PMULLW256 , UNKNOWN, (int) V16HI_FTYPE_V16HI_V16HI },
@@ -28463,6 +28154,967 @@ ix86_init_mmx_sse_builtins (void)
}
}
+/* This adds a condition to the basic_block NEW_BB in function FUNCTION_DECL
+ to return a pointer to VERSION_DECL if the outcome of the expression
+ formed by PREDICATE_CHAIN is true. This function will be called during
+ version dispatch to decide which function version to execute. It returns
+ the basic block at the end, to which more conditions can be added. */
+
+static basic_block
+add_condition_to_bb (tree function_decl, tree version_decl,
+ tree predicate_chain, basic_block new_bb)
+{
+ gimple return_stmt;
+ tree convert_expr, result_var;
+ gimple convert_stmt;
+ gimple call_cond_stmt;
+ gimple if_else_stmt;
+
+ basic_block bb1, bb2, bb3;
+ edge e12, e23;
+
+ tree cond_var, and_expr_var = NULL_TREE;
+ gimple_seq gseq;
+
+ tree predicate_decl, predicate_arg;
+
+ push_cfun (DECL_STRUCT_FUNCTION (function_decl));
+
+ gcc_assert (new_bb != NULL);
+ gseq = bb_seq (new_bb);
+
+
+ convert_expr = build1 (CONVERT_EXPR, ptr_type_node,
+ build_fold_addr_expr (version_decl));
+ result_var = create_tmp_var (ptr_type_node, NULL);
+ convert_stmt = gimple_build_assign (result_var, convert_expr);
+ return_stmt = gimple_build_return (result_var);
+
+ if (predicate_chain == NULL_TREE)
+ {
+ gimple_seq_add_stmt (&gseq, convert_stmt);
+ gimple_seq_add_stmt (&gseq, return_stmt);
+ set_bb_seq (new_bb, gseq);
+ gimple_set_bb (convert_stmt, new_bb);
+ gimple_set_bb (return_stmt, new_bb);
+ pop_cfun ();
+ return new_bb;
+ }
+
+ while (predicate_chain != NULL)
+ {
+ cond_var = create_tmp_var (integer_type_node, NULL);
+ predicate_decl = TREE_PURPOSE (predicate_chain);
+ predicate_arg = TREE_VALUE (predicate_chain);
+ call_cond_stmt = gimple_build_call (predicate_decl, 1, predicate_arg);
+ gimple_call_set_lhs (call_cond_stmt, cond_var);
+
+ gimple_set_block (call_cond_stmt, DECL_INITIAL (function_decl));
+ gimple_set_bb (call_cond_stmt, new_bb);
+ gimple_seq_add_stmt (&gseq, call_cond_stmt);
+
+ predicate_chain = TREE_CHAIN (predicate_chain);
+
+ if (and_expr_var == NULL)
+ and_expr_var = cond_var;
+ else
+ {
+ gimple assign_stmt;
+ /* Use MIN_EXPR to check if any integer is zero?.
+ and_expr_var = min_expr <cond_var, and_expr_var> */
+ assign_stmt = gimple_build_assign (and_expr_var,
+ build2 (MIN_EXPR, integer_type_node,
+ cond_var, and_expr_var));
+
+ gimple_set_block (assign_stmt, DECL_INITIAL (function_decl));
+ gimple_set_bb (assign_stmt, new_bb);
+ gimple_seq_add_stmt (&gseq, assign_stmt);
+ }
+ }
+
+ if_else_stmt = gimple_build_cond (GT_EXPR, and_expr_var,
+ integer_zero_node,
+ NULL_TREE, NULL_TREE);
+ gimple_set_block (if_else_stmt, DECL_INITIAL (function_decl));
+ gimple_set_bb (if_else_stmt, new_bb);
+ gimple_seq_add_stmt (&gseq, if_else_stmt);
+
+ gimple_seq_add_stmt (&gseq, convert_stmt);
+ gimple_seq_add_stmt (&gseq, return_stmt);
+ set_bb_seq (new_bb, gseq);
+
+ bb1 = new_bb;
+ e12 = split_block (bb1, if_else_stmt);
+ bb2 = e12->dest;
+ e12->flags &= ~EDGE_FALLTHRU;
+ e12->flags |= EDGE_TRUE_VALUE;
+
+ e23 = split_block (bb2, return_stmt);
+
+ gimple_set_bb (convert_stmt, bb2);
+ gimple_set_bb (return_stmt, bb2);
+
+ bb3 = e23->dest;
+ make_edge (bb1, bb3, EDGE_FALSE_VALUE);
+
+ remove_edge (e23);
+ make_edge (bb2, EXIT_BLOCK_PTR, 0);
+
+ pop_cfun ();
+
+ return bb3;
+}
+
+/* This parses the attribute arguments to target in DECL and determines
+ the right builtin to use to match the platform specification.
+ It returns the priority value for this version decl. If PREDICATE_LIST
+ is not NULL, it stores the list of cpu features that need to be checked
+ before dispatching this function. */
+
+static unsigned int
+get_builtin_code_for_version (tree decl, tree *predicate_list)
+{
+ tree attrs;
+ struct cl_target_option cur_target;
+ tree target_node;
+ struct cl_target_option *new_target;
+ const char *arg_str = NULL;
+ const char *attrs_str = NULL;
+ char *tok_str = NULL;
+ char *token;
+
+ /* Priority of i386 features, greater value is higher priority. This is
+ used to decide the order in which function dispatch must happen. For
+ instance, a version specialized for SSE4.2 should be checked for dispatch
+ before a version for SSE3, as SSE4.2 implies SSE3. */
+ enum feature_priority
+ {
+ P_ZERO = 0,
+ P_MMX,
+ P_SSE,
+ P_SSE2,
+ P_SSE3,
+ P_SSSE3,
+ P_PROC_SSSE3,
+ P_SSE4_a,
+ P_PROC_SSE4_a,
+ P_SSE4_1,
+ P_SSE4_2,
+ P_PROC_SSE4_2,
+ P_POPCNT,
+ P_AVX,
+ P_AVX2,
+ P_FMA,
+ P_PROC_FMA
+ };
+
+ enum feature_priority priority = P_ZERO;
+
+ /* These are the target attribute strings for which a dispatcher is
+ available, from fold_builtin_cpu. */
+
+ static struct _feature_list
+ {
+ const char *const name;
+ const enum feature_priority priority;
+ }
+ const feature_list[] =
+ {
+ {"mmx", P_MMX},
+ {"sse", P_SSE},
+ {"sse2", P_SSE2},
+ {"sse3", P_SSE3},
+ {"ssse3", P_SSSE3},
+ {"sse4.1", P_SSE4_1},
+ {"sse4.2", P_SSE4_2},
+ {"popcnt", P_POPCNT},
+ {"avx", P_AVX},
+ {"avx2", P_AVX2}
+ };
+
+
+ static unsigned int NUM_FEATURES
+ = sizeof (feature_list) / sizeof (struct _feature_list);
+
+ unsigned int i;
+
+ tree predicate_chain = NULL_TREE;
+ tree predicate_decl, predicate_arg;
+
+ attrs = lookup_attribute ("target", DECL_ATTRIBUTES (decl));
+ gcc_assert (attrs != NULL);
+
+ attrs = TREE_VALUE (TREE_VALUE (attrs));
+
+ gcc_assert (TREE_CODE (attrs) == STRING_CST);
+ attrs_str = TREE_STRING_POINTER (attrs);
+
+
+ /* Handle arch= if specified. For priority, set it to be 1 more than
+ the best instruction set the processor can handle. For instance, if
+ there is a version for atom and a version for ssse3 (the highest ISA
+ priority for atom), the atom version must be checked for dispatch
+ before the ssse3 version. */
+ if (strstr (attrs_str, "arch=") != NULL)
+ {
+ cl_target_option_save (&cur_target, &global_options);
+ target_node = ix86_valid_target_attribute_tree (attrs);
+
+ gcc_assert (target_node);
+ new_target = TREE_TARGET_OPTION (target_node);
+ gcc_assert (new_target);
+
+ if (new_target->arch_specified && new_target->arch > 0)
+ {
+ switch (new_target->arch)
+ {
+ case PROCESSOR_CORE2_32:
+ case PROCESSOR_CORE2_64:
+ arg_str = "core2";
+ priority = P_PROC_SSSE3;
+ break;
+ case PROCESSOR_COREI7_32:
+ case PROCESSOR_COREI7_64:
+ arg_str = "corei7";
+ priority = P_PROC_SSE4_2;
+ break;
+ case PROCESSOR_ATOM:
+ arg_str = "atom";
+ priority = P_PROC_SSSE3;
+ break;
+ case PROCESSOR_AMDFAM10:
+ arg_str = "amdfam10h";
+ priority = P_PROC_SSE4_a;
+ break;
+ case PROCESSOR_BDVER1:
+ arg_str = "bdver1";
+ priority = P_PROC_FMA;
+ break;
+ case PROCESSOR_BDVER2:
+ arg_str = "bdver2";
+ priority = P_PROC_FMA;
+ break;
+ }
+ }
+
+ cl_target_option_restore (&global_options, &cur_target);
+
+ if (predicate_list && arg_str == NULL)
+ {
+ error_at (DECL_SOURCE_LOCATION (decl),
+ "No dispatcher found for the versioning attributes");
+ return 0;
+ }
+
+ if (predicate_list)
+ {
+ predicate_decl = ix86_builtins [(int) IX86_BUILTIN_CPU_IS];
+ /* For a C string literal the length includes the trailing NULL. */
+ predicate_arg = build_string_literal (strlen (arg_str) + 1, arg_str);
+ predicate_chain = tree_cons (predicate_decl, predicate_arg,
+ predicate_chain);
+ }
+ }
+
+ /* Process feature name. */
+ tok_str = (char *) xmalloc (strlen (attrs_str) + 1);
+ strcpy (tok_str, attrs_str);
+ token = strtok (tok_str, ",");
+ predicate_decl = ix86_builtins [(int) IX86_BUILTIN_CPU_SUPPORTS];
+
+ while (token != NULL)
+ {
+ /* Do not process "arch=" */
+ if (strncmp (token, "arch=", 5) == 0)
+ {
+ token = strtok (NULL, ",");
+ continue;
+ }
+ for (i = 0; i < NUM_FEATURES; ++i)
+ {
+ if (strcmp (token, feature_list[i].name) == 0)
+ {
+ if (predicate_list)
+ {
+ predicate_arg = build_string_literal (
+ strlen (feature_list[i].name) + 1,
+ feature_list[i].name);
+ predicate_chain = tree_cons (predicate_decl, predicate_arg,
+ predicate_chain);
+ }
+ /* Find the maximum priority feature. */
+ if (feature_list[i].priority > priority)
+ priority = feature_list[i].priority;
+
+ break;
+ }
+ }
+ if (predicate_list && i == NUM_FEATURES)
+ {
+ error_at (DECL_SOURCE_LOCATION (decl),
+ "No dispatcher found for %s", token);
+ return 0;
+ }
+ token = strtok (NULL, ",");
+ }
+ free (tok_str);
+
+ if (predicate_list && predicate_chain == NULL_TREE)
+ {
+ error_at (DECL_SOURCE_LOCATION (decl),
+ "No dispatcher found for the versioning attributes : %s",
+ attrs_str);
+ return 0;
+ }
+ else if (predicate_list)
+ {
+ predicate_chain = nreverse (predicate_chain);
+ *predicate_list = predicate_chain;
+ }
+
+ return priority;
+}
+
+/* This compares the priority of target features in function DECL1
+ and DECL2. It returns positive value if DECL1 is higher priority,
+ negative value if DECL2 is higher priority and 0 if they are the
+ same. */
+
+static int
+ix86_compare_version_priority (tree decl1, tree decl2)
+{
+ unsigned int priority1 = 0;
+ unsigned int priority2 = 0;
+
+ if (lookup_attribute ("target", DECL_ATTRIBUTES (decl1)) != NULL)
+ priority1 = get_builtin_code_for_version (decl1, NULL);
+
+ if (lookup_attribute ("target", DECL_ATTRIBUTES (decl2)) != NULL)
+ priority2 = get_builtin_code_for_version (decl2, NULL);
+
+ return (int)priority1 - (int)priority2;
+}
+
+/* V1 and V2 point to function versions with different priorities
+ based on the target ISA. This function compares their priorities. */
+
+static int
+feature_compare (const void *v1, const void *v2)
+{
+ typedef struct _function_version_info
+ {
+ tree version_decl;
+ tree predicate_chain;
+ unsigned int dispatch_priority;
+ } function_version_info;
+
+ const function_version_info c1 = *(const function_version_info *)v1;
+ const function_version_info c2 = *(const function_version_info *)v2;
+ return (c2.dispatch_priority - c1.dispatch_priority);
+}
+
+/* This function generates the dispatch function for
+ multi-versioned functions. DISPATCH_DECL is the function which will
+ contain the dispatch logic. FNDECLS are the function choices for
+ dispatch, and is a tree chain. EMPTY_BB is the basic block pointer
+ in DISPATCH_DECL in which the dispatch code is generated. */
+
+static int
+dispatch_function_versions (tree dispatch_decl,
+ void *fndecls_p,
+ basic_block *empty_bb)
+{
+ tree default_decl;
+ gimple ifunc_cpu_init_stmt;
+ gimple_seq gseq;
+ int ix;
+ tree ele;
+ VEC (tree, heap) *fndecls;
+ unsigned int num_versions = 0;
+ unsigned int actual_versions = 0;
+ unsigned int i;
+
+ struct _function_version_info
+ {
+ tree version_decl;
+ tree predicate_chain;
+ unsigned int dispatch_priority;
+ }*function_version_info;
+
+ gcc_assert (dispatch_decl != NULL
+ && fndecls_p != NULL
+ && empty_bb != NULL);
+
+ /*fndecls_p is actually a vector. */
+ fndecls = (VEC (tree, heap) *)fndecls_p;
+
+ /* At least one more version other than the default. */
+ num_versions = VEC_length (tree, fndecls);
+ gcc_assert (num_versions >= 2);
+
+ function_version_info = (struct _function_version_info *)
+ XNEWVEC (struct _function_version_info, (num_versions - 1));
+
+ /* The first version in the vector is the default decl. */
+ default_decl = VEC_index (tree, fndecls, 0);
+
+ push_cfun (DECL_STRUCT_FUNCTION (dispatch_decl));
+
+ gseq = bb_seq (*empty_bb);
+ /* Function version dispatch is via IFUNC. IFUNC resolvers fire before
+ constructors, so explicity call __builtin_cpu_init here. */
+ ifunc_cpu_init_stmt = gimple_build_call_vec (
+ ix86_builtins [(int) IX86_BUILTIN_CPU_INIT], NULL);
+ gimple_seq_add_stmt (&gseq, ifunc_cpu_init_stmt);
+ gimple_set_bb (ifunc_cpu_init_stmt, *empty_bb);
+ set_bb_seq (*empty_bb, gseq);
+
+ pop_cfun ();
+
+
+ for (ix = 1; VEC_iterate (tree, fndecls, ix, ele); ++ix)
+ {
+ tree version_decl = ele;
+ tree predicate_chain = NULL_TREE;
+ unsigned int priority;
+ /* Get attribute string, parse it and find the right predicate decl.
+ The predicate function could be a lengthy combination of many
+ features, like arch-type and various isa-variants. */
+ priority = get_builtin_code_for_version (version_decl,
+ &predicate_chain);
+
+ if (predicate_chain == NULL_TREE)
+ continue;
+
+ actual_versions++;
+ function_version_info [ix - 1].version_decl = version_decl;
+ function_version_info [ix - 1].predicate_chain = predicate_chain;
+ function_version_info [ix - 1].dispatch_priority = priority;
+ }
+
+ /* Sort the versions according to descending order of dispatch priority. The
+ priority is based on the ISA. This is not a perfect solution. There
+ could still be ambiguity. If more than one function version is suitable
+ to execute, which one should be dispatched? In future, allow the user
+ to specify a dispatch priority next to the version. */
+ qsort (function_version_info, actual_versions,
+ sizeof (struct _function_version_info), feature_compare);
+
+ for (i = 0; i < actual_versions; ++i)
+ *empty_bb = add_condition_to_bb (dispatch_decl,
+ function_version_info[i].version_decl,
+ function_version_info[i].predicate_chain,
+ *empty_bb);
+
+ /* dispatch default version at the end. */
+ *empty_bb = add_condition_to_bb (dispatch_decl, default_decl,
+ NULL, *empty_bb);
+
+ free (function_version_info);
+ return 0;
+}
+
+/* This function returns true if FN1 and FN2 are versions of the same function,
+ that is, the targets of the function decls are different. This assumes
+ that FN1 and FN2 have the same signature. */
+
+static bool
+ix86_function_versions (tree fn1, tree fn2)
+{
+ tree attr1, attr2;
+ struct cl_target_option *target1, *target2;
+
+ if (TREE_CODE (fn1) != FUNCTION_DECL
+ || TREE_CODE (fn2) != FUNCTION_DECL)
+ return false;
+
+ attr1 = DECL_FUNCTION_SPECIFIC_TARGET (fn1);
+ attr2 = DECL_FUNCTION_SPECIFIC_TARGET (fn2);
+
+ /* Atleast one function decl should have target attribute specified. */
+ if (attr1 == NULL_TREE && attr2 == NULL_TREE)
+ return false;
+
+ if (attr1 == NULL_TREE)
+ attr1 = target_option_default_node;
+ else if (attr2 == NULL_TREE)
+ attr2 = target_option_default_node;
+
+ target1 = TREE_TARGET_OPTION (attr1);
+ target2 = TREE_TARGET_OPTION (attr2);
+
+ /* target1 and target2 must be different in some way. */
+ if (target1->x_ix86_isa_flags == target2->x_ix86_isa_flags
+ && target1->x_target_flags == target2->x_target_flags
+ && target1->arch == target2->arch
+ && target1->tune == target2->tune
+ && target1->x_ix86_fpmath == target2->x_ix86_fpmath
+ && target1->branch_cost == target2->branch_cost)
+ return false;
+
+ return true;
+}
+
+/* Comparator function to be used in qsort routine to sort attribute
+ specification strings to "target". */
+
+static int
+attr_strcmp (const void *v1, const void *v2)
+{
+ const char *c1 = *(char *const*)v1;
+ const char *c2 = *(char *const*)v2;
+ return strcmp (c1, c2);
+}
+
+/* STR is the argument to target attribute. This function tokenizes
+ the comma separated arguments, sorts them and returns a string which
+ is a unique identifier for the comma separated arguments. It also
+ replaces non-identifier characters "=,-" with "_". */
+
+static char *
+sorted_attr_string (const char *str)
+{
+ char **args = NULL;
+ char *attr_str, *ret_str;
+ char *attr = NULL;
+ unsigned int argnum = 1;
+ unsigned int i;
+
+ for (i = 0; i < strlen (str); i++)
+ if (str[i] == ',')
+ argnum++;
+
+ attr_str = (char *)xmalloc (strlen (str) + 1);
+ strcpy (attr_str, str);
+
+ /* Replace "=,-" with "_". */
+ for (i = 0; i < strlen (attr_str); i++)
+ if (attr_str[i] == '=' || attr_str[i]== '-')
+ attr_str[i] = '_';
+
+ if (argnum == 1)
+ return attr_str;
+
+ args = XNEWVEC (char *, argnum);
+
+ i = 0;
+ attr = strtok (attr_str, ",");
+ while (attr != NULL)
+ {
+ args[i] = attr;
+ i++;
+ attr = strtok (NULL, ",");
+ }
+
+ qsort (args, argnum, sizeof (char*), attr_strcmp);
+
+ ret_str = (char *)xmalloc (strlen (str) + 1);
+ strcpy (ret_str, args[0]);
+ for (i = 1; i < argnum; i++)
+ {
+ strcat (ret_str, "_");
+ strcat (ret_str, args[i]);
+ }
+
+ free (args);
+ free (attr_str);
+ return ret_str;
+}
+
+/* This function changes the assembler name for functions that are
+ versions. If DECL is a function version and has a "target"
+ attribute, it appends the attribute string to its assembler name. */
+
+static tree
+ix86_mangle_function_version_assembler_name (tree decl, tree id)
+{
+ tree version_attr;
+ const char *orig_name, *version_string, *attr_str;
+ char *assembler_name;
+
+ if (DECL_DECLARED_INLINE_P (decl)
+ && lookup_attribute ("gnu_inline",
+ DECL_ATTRIBUTES (decl)))
+ error_at (DECL_SOURCE_LOCATION (decl),
+ "Function versions cannot be marked as gnu_inline,"
+ " bodies have to be generated");
+
+ if (DECL_VIRTUAL_P (decl)
+ || DECL_VINDEX (decl))
+ error_at (DECL_SOURCE_LOCATION (decl),
+ "Virtual function versioning not supported\n");
+
+ version_attr = lookup_attribute ("target", DECL_ATTRIBUTES (decl));
+
+ /* target attribute string is NULL for default functions. */
+ if (version_attr == NULL_TREE)
+ return id;
+
+ orig_name = IDENTIFIER_POINTER (id);
+ version_string
+ = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (version_attr)));
+
+ attr_str = sorted_attr_string (version_string);
+ assembler_name = (char *) xmalloc (strlen (orig_name)
+ + strlen (attr_str) + 2);
+
+ sprintf (assembler_name, "%s.%s", orig_name, attr_str);
+
+ /* Allow assembler name to be modified if already set. */
+ if (DECL_ASSEMBLER_NAME_SET_P (decl))
+ SET_DECL_RTL (decl, NULL);
+
+ return get_identifier (assembler_name);
+}
+
+static tree
+ix86_mangle_decl_assembler_name (tree decl, tree id)
+{
+ /* For function version, add the target suffix to the assembler name. */
+ if (TREE_CODE (decl) == FUNCTION_DECL
+ && DECL_FUNCTION_VERSIONED (decl))
+ return ix86_mangle_function_version_assembler_name (decl, id);
+
+ return id;
+}
+
+/* Return a new name by appending SUFFIX to the DECL name. If make_unique
+ is true, append the full path name of the source file. */
+
+static char *
+make_name (tree decl, const char *suffix, bool make_unique)
+{
+ char *global_var_name;
+ int name_len;
+ const char *name;
+ const char *unique_name = NULL;
+
+ name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
+
+ /* Get a unique name that can be used globally without any chances
+ of collision at link time. */
+ if (make_unique)
+ unique_name = IDENTIFIER_POINTER (get_file_function_name ("\0"));
+
+ name_len = strlen (name) + strlen (suffix) + 2;
+
+ if (make_unique)
+ name_len += strlen (unique_name) + 1;
+ global_var_name = XNEWVEC (char, name_len);
+
+ /* Use '.' to concatenate names as it is demangler friendly. */
+ if (make_unique)
+ snprintf (global_var_name, name_len, "%s.%s.%s", name,
+ unique_name, suffix);
+ else
+ snprintf (global_var_name, name_len, "%s.%s", name, suffix);
+
+ return global_var_name;
+}
+
+/* Make a dispatcher declaration for the multi-versioned function DECL.
+ Calls to DECL function will be replaced with calls to the dispatcher
+ by the front-end. Return the decl created. */
+
+static tree
+make_dispatcher_decl (const tree decl)
+{
+ tree func_decl;
+ char *func_name, *resolver_name;
+ tree fn_type, func_type;
+ bool is_uniq = false;
+
+ if (TREE_PUBLIC (decl) == 0)
+ is_uniq = true;
+
+ func_name = make_name (decl, "ifunc", is_uniq);
+ resolver_name = make_name (decl, "resolver", is_uniq);
+ gcc_assert (resolver_name);
+
+ fn_type = TREE_TYPE (decl);
+ func_type = build_function_type (TREE_TYPE (fn_type),
+ TYPE_ARG_TYPES (fn_type));
+
+ func_decl = build_fn_decl (func_name, func_type);
+ TREE_USED (func_decl) = 1;
+ DECL_CONTEXT (func_decl) = NULL_TREE;
+ DECL_INITIAL (func_decl) = error_mark_node;
+ DECL_ARTIFICIAL (func_decl) = 1;
+ /* Mark this func as external, the resolver will flip it again if
+ it gets generated. */
+ DECL_EXTERNAL (func_decl) = 1;
+ /* This will be of type IFUNCs have to be externally visible. */
+ TREE_PUBLIC (func_decl) = 1;
+
+ return func_decl;
+}
+
+/* Returns true if decl is multi-versioned and DECL is the default function,
+ that is it is not tagged with target specific optimization. */
+
+static bool
+is_function_default_version (const tree decl)
+{
+ return (TREE_CODE (decl) == FUNCTION_DECL
+ && DECL_FUNCTION_VERSIONED (decl)
+ && DECL_FUNCTION_SPECIFIC_TARGET (decl) == NULL_TREE);
+}
+
+/* Make a dispatcher declaration for the multi-versioned function DECL.
+ Calls to DECL function will be replaced with calls to the dispatcher
+ by the front-end. Returns the decl of the dispatcher function. */
+
+static tree
+ix86_get_function_versions_dispatcher (void *decl)
+{
+ tree fn = (tree) decl;
+ struct cgraph_node *node = NULL;
+ struct cgraph_node *default_node = NULL;
+ struct cgraph_function_version_info *node_v = NULL;
+ struct cgraph_function_version_info *it_v = NULL;
+ struct cgraph_function_version_info *first_v = NULL;
+
+ tree dispatch_decl = NULL;
+ struct cgraph_node *dispatcher_node = NULL;
+ struct cgraph_function_version_info *dispatcher_version_info = NULL;
+
+ struct cgraph_function_version_info *default_version_info = NULL;
+
+ gcc_assert (fn != NULL && DECL_FUNCTION_VERSIONED (fn));
+
+ node = cgraph_get_node (fn);
+ gcc_assert (node != NULL);
+
+ node_v = get_cgraph_node_version (node);
+ gcc_assert (node_v != NULL);
+
+ if (node_v->dispatcher_resolver != NULL)
+ return node_v->dispatcher_resolver;
+
+ /* Find the default version and make it the first node. */
+ first_v = node_v;
+ /* Go to the beginnig of the chain. */
+ while (first_v->prev != NULL)
+ first_v = first_v->prev;
+ default_version_info = first_v;
+ while (default_version_info != NULL)
+ {
+ if (is_function_default_version
+ (default_version_info->this_node->symbol.decl))
+ break;
+ default_version_info = default_version_info->next;
+ }
+
+ /* If there is no default node, just return NULL. */
+ if (default_version_info == NULL)
+ return NULL;
+
+ /* Make default info the first node. */
+ if (first_v != default_version_info)
+ {
+ default_version_info->prev->next = default_version_info->next;
+ if (default_version_info->next)
+ default_version_info->next->prev = default_version_info->prev;
+ first_v->prev = default_version_info;
+ default_version_info->next = first_v;
+ default_version_info->prev = NULL;
+ }
+
+ default_node = default_version_info->this_node;
+
+#if defined (ASM_OUTPUT_TYPE_DIRECTIVE) && HAVE_GNU_INDIRECT_FUNCTION
+ /* Right now, the dispatching is done via ifunc. */
+ dispatch_decl = make_dispatcher_decl (default_node->symbol.decl);
+#else
+ error_at (DECL_SOURCE_LOCATION (default_node->symbol.decl),
+ "Multiversioning needs ifunc which is not supported "
+ "in this configuration");
+#endif
+
+ dispatcher_node = cgraph_get_create_node (dispatch_decl);
+ gcc_assert (dispatcher_node != NULL);
+ dispatcher_node->dispatcher_function = 1;
+ dispatcher_version_info
+ = insert_new_cgraph_node_version (dispatcher_node);
+ dispatcher_version_info->next = default_version_info;
+ dispatcher_node->local.finalized = 1;
+
+ /* Set the dispatcher for all the versions. */
+ it_v = default_version_info;
+ while (it_v->next != NULL)
+ {
+ it_v->dispatcher_resolver = dispatch_decl;
+ it_v = it_v->next;
+ }
+
+ return dispatch_decl;
+}
+
+/* Makes a function attribute of the form NAME(ARG_NAME) and chains
+ it to CHAIN. */
+
+static tree
+make_attribute (const char *name, const char *arg_name, tree chain)
+{
+ tree attr_name;
+ tree attr_arg_name;
+ tree attr_args;
+ tree attr;
+
+ attr_name = get_identifier (name);
+ attr_arg_name = build_string (strlen (arg_name), arg_name);
+ attr_args = tree_cons (NULL_TREE, attr_arg_name, NULL_TREE);
+ attr = tree_cons (attr_name, attr_args, chain);
+ return attr;
+}
+
+/* Make the resolver function decl to dispatch the versions of
+ a multi-versioned function, DEFAULT_DECL. Create an
+ empty basic block in the resolver and store the pointer in
+ EMPTY_BB. Return the decl of the resolver function. */
+
+static tree
+make_resolver_func (const tree default_decl,
+ const tree dispatch_decl,
+ basic_block *empty_bb)
+{
+ char *resolver_name;
+ tree decl, type, decl_name, t;
+ bool is_uniq = false;
+
+ /* IFUNC's have to be globally visible. So, if the default_decl is
+ not, then the name of the IFUNC should be made unique. */
+ if (TREE_PUBLIC (default_decl) == 0)
+ is_uniq = true;
+
+ /* Append the filename to the resolver function if the versions are
+ not externally visible. This is because the resolver function has
+ to be externally visible for the loader to find it. So, appending
+ the filename will prevent conflicts with a resolver function from
+ another module which is based on the same version name. */
+ resolver_name = make_name (default_decl, "resolver", is_uniq);
+
+ /* The resolver function should return a (void *). */
+ type = build_function_type_list (ptr_type_node, NULL_TREE);
+
+ decl = build_fn_decl (resolver_name, type);
+ decl_name = get_identifier (resolver_name);
+ SET_DECL_ASSEMBLER_NAME (decl, decl_name);
+
+ DECL_NAME (decl) = decl_name;
+ TREE_USED (decl) = 1;
+ DECL_ARTIFICIAL (decl) = 1;
+ DECL_IGNORED_P (decl) = 0;
+ /* IFUNC resolvers have to be externally visible. */
+ TREE_PUBLIC (decl) = 1;
+ DECL_UNINLINABLE (decl) = 0;
+
+ /* Resolver is not external, body is generated. */
+ DECL_EXTERNAL (decl) = 0;
+ DECL_EXTERNAL (dispatch_decl) = 0;
+
+ DECL_CONTEXT (decl) = NULL_TREE;
+ DECL_INITIAL (decl) = make_node (BLOCK);
+ DECL_STATIC_CONSTRUCTOR (decl) = 0;
+
+ if (DECL_COMDAT_GROUP (default_decl)
+ || TREE_PUBLIC (default_decl))
+ {
+ /* In this case, each translation unit with a call to this
+ versioned function will put out a resolver. Ensure it
+ is comdat to keep just one copy. */
+ DECL_COMDAT (decl) = 1;
+ make_decl_one_only (decl, DECL_ASSEMBLER_NAME (decl));
+ }
+ /* Build result decl and add to function_decl. */
+ t = build_decl (UNKNOWN_LOCATION, RESULT_DECL, NULL_TREE, ptr_type_node);
+ DECL_ARTIFICIAL (t) = 1;
+ DECL_IGNORED_P (t) = 1;
+ DECL_RESULT (decl) = t;
+
+ gimplify_function_tree (decl);
+ push_cfun (DECL_STRUCT_FUNCTION (decl));
+ *empty_bb = init_lowered_empty_function (decl, false);
+
+ cgraph_add_new_function (decl, true);
+ cgraph_call_function_insertion_hooks (cgraph_get_create_node (decl));
+
+ pop_cfun ();
+
+ gcc_assert (dispatch_decl != NULL);
+ /* Mark dispatch_decl as "ifunc" with resolver as resolver_name. */
+ DECL_ATTRIBUTES (dispatch_decl)
+ = make_attribute ("ifunc", resolver_name, DECL_ATTRIBUTES (dispatch_decl));
+
+ /* Create the alias for dispatch to resolver here. */
+ /*cgraph_create_function_alias (dispatch_decl, decl);*/
+ cgraph_same_body_alias (NULL, dispatch_decl, decl);
+ return decl;
+}
+
+/* Generate the dispatching code body to dispatch multi-versioned function
+ DECL. The target hook is called to process the "target" attributes and
+ provide the code to dispatch the right function at run-time. NODE points
+ to the dispatcher decl whose body will be created. */
+
+static tree
+ix86_generate_version_dispatcher_body (void *node_p)
+{
+ tree resolver_decl;
+ basic_block empty_bb;
+ VEC (tree, heap) *fn_ver_vec = NULL;
+ tree default_ver_decl;
+ struct cgraph_node *versn;
+ struct cgraph_node *node;
+
+ struct cgraph_function_version_info *node_version_info = NULL;
+ struct cgraph_function_version_info *versn_info = NULL;
+
+ node = (cgraph_node *)node_p;
+
+ node_version_info = get_cgraph_node_version (node);
+ gcc_assert (node->dispatcher_function
+ && node_version_info != NULL);
+
+ if (node_version_info->dispatcher_resolver)
+ return node_version_info->dispatcher_resolver;
+
+ /* The first version in the chain corresponds to the default version. */
+ default_ver_decl = node_version_info->next->this_node->symbol.decl;
+
+ /* node is going to be an alias, so remove the finalized bit. */
+ node->local.finalized = false;
+
+ resolver_decl = make_resolver_func (default_ver_decl,
+ node->symbol.decl, &empty_bb);
+
+ node_version_info->dispatcher_resolver = resolver_decl;
+
+ push_cfun (DECL_STRUCT_FUNCTION (resolver_decl));
+
+ fn_ver_vec = VEC_alloc (tree, heap, 2);
+
+ for (versn_info = node_version_info->next; versn_info;
+ versn_info = versn_info->next)
+ {
+ versn = versn_info->this_node;
+ /* Check for virtual functions here again, as by this time it should
+ have been determined if this function needs a vtable index or
+ not. This happens for methods in derived classes that override
+ virtual methods in base classes but are not explicitly marked as
+ virtual. */
+ if (DECL_VINDEX (versn->symbol.decl))
+ error_at (DECL_SOURCE_LOCATION (versn->symbol.decl),
+ "Virtual function multiversioning not supported");
+ VEC_safe_push (tree, heap, fn_ver_vec, versn->symbol.decl);
+ }
+
+ dispatch_function_versions (resolver_decl, fn_ver_vec, &empty_bb);
+
+ rebuild_cgraph_edges ();
+ pop_cfun ();
+ return resolver_decl;
+}
/* This builds the processor_model struct type defined in
libgcc/config/i386/cpuinfo.c */
@@ -28651,6 +29303,8 @@ fold_builtin_cpu (tree fndecl, tree *args)
{
tree ref;
tree field;
+ tree final;
+
unsigned int field_val = 0;
unsigned int NUM_ARCH_NAMES
= sizeof (arch_names_table) / sizeof (struct _arch_names_table);
@@ -28690,14 +29344,17 @@ fold_builtin_cpu (tree fndecl, tree *args)
field, NULL_TREE);
/* Check the value. */
- return build2 (EQ_EXPR, unsigned_type_node, ref,
- build_int_cstu (unsigned_type_node, field_val));
+ final = build2 (EQ_EXPR, unsigned_type_node, ref,
+ build_int_cstu (unsigned_type_node, field_val));
+ return build1 (CONVERT_EXPR, integer_type_node, final);
}
else if (fn_code == IX86_BUILTIN_CPU_SUPPORTS)
{
tree ref;
tree array_elt;
tree field;
+ tree final;
+
unsigned int field_val = 0;
unsigned int NUM_ISA_NAMES
= sizeof (isa_names_table) / sizeof (struct _isa_names_table);
@@ -28729,8 +29386,9 @@ fold_builtin_cpu (tree fndecl, tree *args)
field_val = (1 << isa_names_table[i].feature);
/* Return __cpu_model.__cpu_features[0] & field_val */
- return build2 (BIT_AND_EXPR, unsigned_type_node, array_elt,
- build_int_cstu (unsigned_type_node, field_val));
+ final = build2 (BIT_AND_EXPR, unsigned_type_node, array_elt,
+ build_int_cstu (unsigned_type_node, field_val));
+ return build1 (CONVERT_EXPR, integer_type_node, final);
}
gcc_unreachable ();
}
@@ -30168,8 +30826,6 @@ ix86_expand_special_args_builtin (const struct builtin_description *d,
switch ((enum ix86_builtin_func_type) d->flag)
{
case VOID_FTYPE_VOID:
- if (icode == CODE_FOR_avx_vzeroupper)
- target = GEN_INT (vzeroupper_intrinsic);
emit_insn (GEN_FCN (icode) (target));
return 0;
case VOID_FTYPE_UINT64:
@@ -30586,13 +31242,13 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
case IX86_BUILTIN_LDMXCSR:
op0 = expand_normal (CALL_EXPR_ARG (exp, 0));
- target = assign_386_stack_local (SImode, SLOT_VIRTUAL);
+ target = assign_386_stack_local (SImode, SLOT_TEMP);
emit_move_insn (target, op0);
emit_insn (gen_sse_ldmxcsr (target));
return 0;
case IX86_BUILTIN_STMXCSR:
- target = assign_386_stack_local (SImode, SLOT_VIRTUAL);
+ target = assign_386_stack_local (SImode, SLOT_TEMP);
emit_insn (gen_sse_stmxcsr (target));
return copy_to_mode_reg (SImode, target);
@@ -34403,10 +35059,6 @@ ix86_reorg (void)
with old MDEP_REORGS that are not CFG based. Recompute it now. */
compute_bb_for_insn ();
- /* Run the vzeroupper optimization if needed. */
- if (TARGET_VZEROUPPER)
- move_or_delete_vzeroupper ();
-
if (optimize && optimize_function_for_speed_p (cfun))
{
if (TARGET_PAD_SHORT_FUNCTION)
@@ -41218,6 +41870,9 @@ ix86_memmodel_check (unsigned HOST_WIDE_INT val)
#undef TARGET_PROFILE_BEFORE_PROLOGUE
#define TARGET_PROFILE_BEFORE_PROLOGUE ix86_profile_before_prologue
+#undef TARGET_MANGLE_DECL_ASSEMBLER_NAME
+#define TARGET_MANGLE_DECL_ASSEMBLER_NAME ix86_mangle_decl_assembler_name
+
#undef TARGET_ASM_UNALIGNED_HI_OP
#define TARGET_ASM_UNALIGNED_HI_OP TARGET_ASM_ALIGNED_HI_OP
#undef TARGET_ASM_UNALIGNED_SI_OP
@@ -41311,6 +41966,17 @@ ix86_memmodel_check (unsigned HOST_WIDE_INT val)
#undef TARGET_FOLD_BUILTIN
#define TARGET_FOLD_BUILTIN ix86_fold_builtin
+#undef TARGET_COMPARE_VERSION_PRIORITY
+#define TARGET_COMPARE_VERSION_PRIORITY ix86_compare_version_priority
+
+#undef TARGET_GENERATE_VERSION_DISPATCHER_BODY
+#define TARGET_GENERATE_VERSION_DISPATCHER_BODY \
+ ix86_generate_version_dispatcher_body
+
+#undef TARGET_GET_FUNCTION_VERSIONS_DISPATCHER
+#define TARGET_GET_FUNCTION_VERSIONS_DISPATCHER \
+ ix86_get_function_versions_dispatcher
+
#undef TARGET_ENUM_VA_LIST_P
#define TARGET_ENUM_VA_LIST_P ix86_enum_va_list
@@ -41402,6 +42068,9 @@ ix86_memmodel_check (unsigned HOST_WIDE_INT val)
#undef TARGET_MEMBER_TYPE_FORCES_BLK
#define TARGET_MEMBER_TYPE_FORCES_BLK ix86_member_type_forces_blk
+#undef TARGET_INSTANTIATE_DECLS
+#define TARGET_INSTANTIATE_DECLS ix86_instantiate_decls
+
#undef TARGET_SECONDARY_RELOAD
#define TARGET_SECONDARY_RELOAD ix86_secondary_reload
@@ -41451,6 +42120,9 @@ ix86_memmodel_check (unsigned HOST_WIDE_INT val)
#undef TARGET_OPTION_PRINT
#define TARGET_OPTION_PRINT ix86_function_specific_print
+#undef TARGET_OPTION_FUNCTION_VERSIONS
+#define TARGET_OPTION_FUNCTION_VERSIONS ix86_function_versions
+
#undef TARGET_CAN_INLINE_P
#define TARGET_CAN_INLINE_P ix86_can_inline_p
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 712d00a5ed8..18d476dc60f 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -1035,6 +1035,9 @@ enum target_cpu_default
|| (MODE) == V4DImode || (MODE) == V2TImode || (MODE) == V8SFmode \
|| (MODE) == V4DFmode)
+#define VALID_AVX256_REG_OR_OI_MODE(MODE) \
+ (VALID_AVX256_REG_MODE (MODE) || (MODE) == OImode)
+
#define VALID_SSE2_REG_MODE(MODE) \
((MODE) == V16QImode || (MODE) == V8HImode || (MODE) == V2DFmode \
|| (MODE) == V2DImode || (MODE) == DFmode)
@@ -2141,7 +2144,8 @@ enum ix86_fpcmp_strategy {
enum ix86_entity
{
- I387_TRUNC = 0,
+ AVX_U128 = 0,
+ I387_TRUNC,
I387_FLOOR,
I387_CEIL,
I387_MASK_PM,
@@ -2150,8 +2154,7 @@ enum ix86_entity
enum ix86_stack_slot
{
- SLOT_VIRTUAL = 0,
- SLOT_TEMP,
+ SLOT_TEMP = 0,
SLOT_CW_STORED,
SLOT_CW_TRUNC,
SLOT_CW_FLOOR,
@@ -2160,6 +2163,13 @@ enum ix86_stack_slot
MAX_386_STACK_LOCALS
};
+enum avx_u128_state
+{
+ AVX_U128_CLEAN,
+ AVX_U128_DIRTY,
+ AVX_U128_ANY
+};
+
/* Define this macro if the port needs extra instructions inserted
for mode switching in an optimizing compilation. */
@@ -2175,16 +2185,34 @@ enum ix86_stack_slot
refer to the mode-switched entity in question. */
#define NUM_MODES_FOR_MODE_SWITCHING \
- { I387_CW_ANY, I387_CW_ANY, I387_CW_ANY, I387_CW_ANY }
+ { AVX_U128_ANY, I387_CW_ANY, I387_CW_ANY, I387_CW_ANY, I387_CW_ANY }
/* ENTITY is an integer specifying a mode-switched entity. If
`OPTIMIZE_MODE_SWITCHING' is defined, you must define this macro to
return an integer value not larger than the corresponding element
in `NUM_MODES_FOR_MODE_SWITCHING', to denote the mode that ENTITY
- must be switched into prior to the execution of INSN. */
+ must be switched into prior to the execution of INSN. */
#define MODE_NEEDED(ENTITY, I) ix86_mode_needed ((ENTITY), (I))
+/* If this macro is defined, it is evaluated for every INSN during
+ mode switching. It determines the mode that an insn results in (if
+ different from the incoming mode). */
+
+#define MODE_AFTER(ENTITY, MODE, I) ix86_mode_after ((ENTITY), (MODE), (I))
+
+/* If this macro is defined, it is evaluated for every ENTITY that
+ needs mode switching. It should evaluate to an integer, which is
+ a mode that ENTITY is assumed to be switched to at function entry. */
+
+#define MODE_ENTRY(ENTITY) ix86_mode_entry (ENTITY)
+
+/* If this macro is defined, it is evaluated for every ENTITY that
+ needs mode switching. It should evaluate to an integer, which is
+ a mode that ENTITY is assumed to be switched to at function exit. */
+
+#define MODE_EXIT(ENTITY) ix86_mode_exit (ENTITY)
+
/* This macro specifies the order in which modes for ENTITY are
processed. 0 is the highest priority. */
@@ -2194,11 +2222,8 @@ enum ix86_stack_slot
is the set of hard registers live at the point where the insn(s)
are to be inserted. */
-#define EMIT_MODE_SET(ENTITY, MODE, HARD_REGS_LIVE) \
- ((MODE) != I387_CW_ANY && (MODE) != I387_CW_UNINITIALIZED \
- ? emit_i387_cw_initialization (MODE), 0 \
- : 0)
-
+#define EMIT_MODE_SET(ENTITY, MODE, HARD_REGS_LIVE) \
+ ix86_emit_mode_set ((ENTITY), (MODE))
/* Avoid renaming of stack registers, as doing so in combination with
scheduling just increases amount of live registers at time and in
@@ -2299,21 +2324,6 @@ struct GTY(()) machine_function {
stack below the return address. */
BOOL_BITFIELD static_chain_on_stack : 1;
- /* Nonzero if caller passes 256bit AVX modes. */
- BOOL_BITFIELD caller_pass_avx256_p : 1;
-
- /* Nonzero if caller returns 256bit AVX modes. */
- BOOL_BITFIELD caller_return_avx256_p : 1;
-
- /* Nonzero if the current callee passes 256bit AVX modes. */
- BOOL_BITFIELD callee_pass_avx256_p : 1;
-
- /* Nonzero if the current callee returns 256bit AVX modes. */
- BOOL_BITFIELD callee_return_avx256_p : 1;
-
- /* Nonzero if rescan vzerouppers in the current function is needed. */
- BOOL_BITFIELD rescan_vzeroupper_p : 1;
-
/* During prologue/epilogue generation, the current frame state.
Otherwise, the frame state at the end of the prologue. */
struct machine_frame_state fs;
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 61d3ccdd274..243ab4ee2f8 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -109,7 +109,6 @@
UNSPEC_TRUNC_NOOP
UNSPEC_DIV_ALREADY_SPLIT
UNSPEC_MS_TO_SYSV_CALL
- UNSPEC_CALL_NEEDS_VZEROUPPER
UNSPEC_PAUSE
UNSPEC_LEA_ADDR
UNSPEC_XBEGIN_ABORT
@@ -4071,10 +4070,7 @@
;
else
{
- enum ix86_stack_slot slot = (virtuals_instantiated
- ? SLOT_TEMP
- : SLOT_VIRTUAL);
- rtx temp = assign_386_stack_local (SFmode, slot);
+ rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
DONE;
}
@@ -4255,12 +4251,7 @@
DONE;
}
else
- {
- enum ix86_stack_slot slot = (virtuals_instantiated
- ? SLOT_TEMP
- : SLOT_VIRTUAL);
- operands[2] = assign_386_stack_local (<MODE>mode, slot);
- }
+ operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
})
(define_insn "*truncxfsf2_mixed"
@@ -5468,12 +5459,7 @@
DONE;
}
else
- {
- enum ix86_stack_slot slot = (virtuals_instantiated
- ? SLOT_TEMP
- : SLOT_VIRTUAL);
- operands[2] = assign_386_stack_local (DImode, slot);
- }
+ operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
})
(define_expand "floatunsdisf2"
@@ -11503,18 +11489,6 @@
DONE;
})
-(define_insn_and_split "*call_vzeroupper"
- [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
- (match_operand 1))
- (unspec [(match_operand 2 "const_int_operand")]
- UNSPEC_CALL_NEEDS_VZEROUPPER)]
- "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
- "#"
- "&& reload_completed"
- [(const_int 0)]
- "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
- [(set_attr "type" "call")])
-
(define_insn "*call"
[(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
(match_operand 1))]
@@ -11522,31 +11496,6 @@
"* return ix86_output_call_insn (insn, operands[0]);"
[(set_attr "type" "call")])
-(define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
- [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
- (match_operand 1))
- (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
- (clobber (reg:TI XMM6_REG))
- (clobber (reg:TI XMM7_REG))
- (clobber (reg:TI XMM8_REG))
- (clobber (reg:TI XMM9_REG))
- (clobber (reg:TI XMM10_REG))
- (clobber (reg:TI XMM11_REG))
- (clobber (reg:TI XMM12_REG))
- (clobber (reg:TI XMM13_REG))
- (clobber (reg:TI XMM14_REG))
- (clobber (reg:TI XMM15_REG))
- (clobber (reg:DI SI_REG))
- (clobber (reg:DI DI_REG))
- (unspec [(match_operand 2 "const_int_operand")]
- UNSPEC_CALL_NEEDS_VZEROUPPER)]
- "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
- "#"
- "&& reload_completed"
- [(const_int 0)]
- "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
- [(set_attr "type" "call")])
-
(define_insn "*call_rex64_ms_sysv"
[(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
(match_operand 1))
@@ -11567,18 +11516,6 @@
"* return ix86_output_call_insn (insn, operands[0]);"
[(set_attr "type" "call")])
-(define_insn_and_split "*sibcall_vzeroupper"
- [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
- (match_operand 1))
- (unspec [(match_operand 2 "const_int_operand")]
- UNSPEC_CALL_NEEDS_VZEROUPPER)]
- "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
- "#"
- "&& reload_completed"
- [(const_int 0)]
- "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
- [(set_attr "type" "call")])
-
(define_insn "*sibcall"
[(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
(match_operand 1))]
@@ -11599,21 +11536,6 @@
DONE;
})
-(define_insn_and_split "*call_pop_vzeroupper"
- [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
- (match_operand 1))
- (set (reg:SI SP_REG)
- (plus:SI (reg:SI SP_REG)
- (match_operand:SI 2 "immediate_operand" "i")))
- (unspec [(match_operand 3 "const_int_operand")]
- UNSPEC_CALL_NEEDS_VZEROUPPER)]
- "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
- "#"
- "&& reload_completed"
- [(const_int 0)]
- "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
- [(set_attr "type" "call")])
-
(define_insn "*call_pop"
[(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
(match_operand 1))
@@ -11624,21 +11546,6 @@
"* return ix86_output_call_insn (insn, operands[0]);"
[(set_attr "type" "call")])
-(define_insn_and_split "*sibcall_pop_vzeroupper"
- [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
- (match_operand 1))
- (set (reg:SI SP_REG)
- (plus:SI (reg:SI SP_REG)
- (match_operand:SI 2 "immediate_operand" "i")))
- (unspec [(match_operand 3 "const_int_operand")]
- UNSPEC_CALL_NEEDS_VZEROUPPER)]
- "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
- "#"
- "&& reload_completed"
- [(const_int 0)]
- "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
- [(set_attr "type" "call")])
-
(define_insn "*sibcall_pop"
[(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
(match_operand 1))
@@ -11675,19 +11582,6 @@
DONE;
})
-(define_insn_and_split "*call_value_vzeroupper"
- [(set (match_operand 0)
- (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
- (match_operand 2)))
- (unspec [(match_operand 3 "const_int_operand")]
- UNSPEC_CALL_NEEDS_VZEROUPPER)]
- "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
- "#"
- "&& reload_completed"
- [(const_int 0)]
- "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
- [(set_attr "type" "callv")])
-
(define_insn "*call_value"
[(set (match_operand 0)
(call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
@@ -11696,19 +11590,6 @@
"* return ix86_output_call_insn (insn, operands[1]);"
[(set_attr "type" "callv")])
-(define_insn_and_split "*sibcall_value_vzeroupper"
- [(set (match_operand 0)
- (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
- (match_operand 2)))
- (unspec [(match_operand 3 "const_int_operand")]
- UNSPEC_CALL_NEEDS_VZEROUPPER)]
- "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
- "#"
- "&& reload_completed"
- [(const_int 0)]
- "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
- [(set_attr "type" "callv")])
-
(define_insn "*sibcall_value"
[(set (match_operand 0)
(call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
@@ -11717,32 +11598,6 @@
"* return ix86_output_call_insn (insn, operands[1]);"
[(set_attr "type" "callv")])
-(define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
- [(set (match_operand 0)
- (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
- (match_operand 2)))
- (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
- (clobber (reg:TI XMM6_REG))
- (clobber (reg:TI XMM7_REG))
- (clobber (reg:TI XMM8_REG))
- (clobber (reg:TI XMM9_REG))
- (clobber (reg:TI XMM10_REG))
- (clobber (reg:TI XMM11_REG))
- (clobber (reg:TI XMM12_REG))
- (clobber (reg:TI XMM13_REG))
- (clobber (reg:TI XMM14_REG))
- (clobber (reg:TI XMM15_REG))
- (clobber (reg:DI SI_REG))
- (clobber (reg:DI DI_REG))
- (unspec [(match_operand 3 "const_int_operand")]
- UNSPEC_CALL_NEEDS_VZEROUPPER)]
- "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
- "#"
- "&& reload_completed"
- [(const_int 0)]
- "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
- [(set_attr "type" "callv")])
-
(define_insn "*call_value_rex64_ms_sysv"
[(set (match_operand 0)
(call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
@@ -11778,22 +11633,6 @@
DONE;
})
-(define_insn_and_split "*call_value_pop_vzeroupper"
- [(set (match_operand 0)
- (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
- (match_operand 2)))
- (set (reg:SI SP_REG)
- (plus:SI (reg:SI SP_REG)
- (match_operand:SI 3 "immediate_operand" "i")))
- (unspec [(match_operand 4 "const_int_operand")]
- UNSPEC_CALL_NEEDS_VZEROUPPER)]
- "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
- "#"
- "&& reload_completed"
- [(const_int 0)]
- "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
- [(set_attr "type" "callv")])
-
(define_insn "*call_value_pop"
[(set (match_operand 0)
(call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
@@ -11805,22 +11644,6 @@
"* return ix86_output_call_insn (insn, operands[1]);"
[(set_attr "type" "callv")])
-(define_insn_and_split "*sibcall_value_pop_vzeroupper"
- [(set (match_operand 0)
- (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
- (match_operand 2)))
- (set (reg:SI SP_REG)
- (plus:SI (reg:SI SP_REG)
- (match_operand:SI 3 "immediate_operand" "i")))
- (unspec [(match_operand 4 "const_int_operand")]
- UNSPEC_CALL_NEEDS_VZEROUPPER)]
- "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
- "#"
- "&& reload_completed"
- [(const_int 0)]
- "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
- [(set_attr "type" "callv")])
-
(define_insn "*sibcall_value_pop"
[(set (match_operand 0)
(call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
@@ -11922,7 +11745,6 @@
[(simple_return)]
"ix86_can_use_return_insn_p ()"
{
- ix86_maybe_emit_epilogue_vzeroupper ();
if (crtl->args.pops_args)
{
rtx popc = GEN_INT (crtl->args.pops_args);
@@ -11939,7 +11761,6 @@
[(simple_return)]
"!TARGET_SEH"
{
- ix86_maybe_emit_epilogue_vzeroupper ();
if (crtl->args.pops_args)
{
rtx popc = GEN_INT (crtl->args.pops_args);
@@ -15563,10 +15384,7 @@
emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
else
{
- enum ix86_stack_slot slot = (virtuals_instantiated
- ? SLOT_TEMP
- : SLOT_VIRTUAL);
- rtx temp = assign_386_stack_local (<MODE>mode, slot);
+ rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
emit_move_insn (temp, operands[1]);
emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md
index 4e5c17d8b37..e1085534b91 100644
--- a/gcc/config/i386/predicates.md
+++ b/gcc/config/i386/predicates.md
@@ -568,10 +568,14 @@
return op == CONST0_RTX (mode);
})
-;; Match exactly one.
+;; Match one or vector filled with ones.
(define_predicate "const1_operand"
- (and (match_code "const_int")
- (match_test "op == const1_rtx")))
+ (match_code "const_int,const_double,const_vector")
+{
+ if (mode == VOIDmode)
+ mode = GET_MODE (op);
+ return op == CONST1_RTX (mode);
+})
;; Match exactly eight.
(define_predicate "const8_operand"
@@ -1225,6 +1229,13 @@
return true;
})
+;; return true if OP is a vzeroupper operation.
+(define_predicate "vzeroupper_operation"
+ (match_code "unspec_volatile")
+{
+ return XINT (op, 1) == UNSPECV_VZEROUPPER;
+})
+
;; Return true if OP is a parallel for a vbroadcast permute.
(define_predicate "avx_vbroadcast_operand"
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index 299b0d936d7..33d7b6bc0a9 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -222,7 +222,7 @@
(define_mode_attr ssse3_avx2
[(V16QI "ssse3") (V32QI "avx2")
- (V8HI "ssse3") (V16HI "avx2")
+ (V4HI "ssse3") (V8HI "ssse3") (V16HI "avx2")
(V4SI "ssse3") (V8SI "avx2")
(V2DI "ssse3") (V4DI "avx2")
(TI "ssse3") (V2TI "avx2")])
@@ -246,7 +246,8 @@
(V2DI "vec") (V4DI "avx2")])
(define_mode_attr ssedoublemode
- [(V16HI "V16SI") (V8HI "V8SI")])
+ [(V16HI "V16SI") (V8HI "V8SI") (V4HI "V4SI")
+ (V32QI "V32HI") (V16QI "V16HI")])
(define_mode_attr ssebytemode
[(V4DI "V32QI") (V2DI "V16QI")])
@@ -7637,209 +7638,45 @@
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(define_expand "avx2_uavgv32qi3"
- [(set (match_operand:V32QI 0 "register_operand")
- (truncate:V32QI
- (lshiftrt:V32HI
- (plus:V32HI
- (plus:V32HI
- (zero_extend:V32HI
- (match_operand:V32QI 1 "nonimmediate_operand"))
- (zero_extend:V32HI
- (match_operand:V32QI 2 "nonimmediate_operand")))
- (const_vector:V32QI [(const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)]))
- (const_int 1))))]
- "TARGET_AVX2"
- "ix86_fixup_binary_operands_no_copy (PLUS, V32QImode, operands);")
-
-(define_expand "sse2_uavgv16qi3"
- [(set (match_operand:V16QI 0 "register_operand")
- (truncate:V16QI
- (lshiftrt:V16HI
- (plus:V16HI
- (plus:V16HI
- (zero_extend:V16HI
- (match_operand:V16QI 1 "nonimmediate_operand"))
- (zero_extend:V16HI
- (match_operand:V16QI 2 "nonimmediate_operand")))
- (const_vector:V16QI [(const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)]))
- (const_int 1))))]
- "TARGET_SSE2"
- "ix86_fixup_binary_operands_no_copy (PLUS, V16QImode, operands);")
-
-(define_insn "*avx2_uavgv32qi3"
- [(set (match_operand:V32QI 0 "register_operand" "=x")
- (truncate:V32QI
- (lshiftrt:V32HI
- (plus:V32HI
- (plus:V32HI
- (zero_extend:V32HI
- (match_operand:V32QI 1 "nonimmediate_operand" "%x"))
- (zero_extend:V32HI
- (match_operand:V32QI 2 "nonimmediate_operand" "xm")))
- (const_vector:V32QI [(const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)]))
- (const_int 1))))]
- "TARGET_AVX2 && ix86_binary_operator_ok (PLUS, V32QImode, operands)"
- "vpavgb\t{%2, %1, %0|%0, %1, %2}"
- [(set_attr "type" "sseiadd")
- (set_attr "prefix" "vex")
- (set_attr "mode" "OI")])
-
-(define_insn "*sse2_uavgv16qi3"
- [(set (match_operand:V16QI 0 "register_operand" "=x,x")
- (truncate:V16QI
- (lshiftrt:V16HI
- (plus:V16HI
- (plus:V16HI
- (zero_extend:V16HI
- (match_operand:V16QI 1 "nonimmediate_operand" "%0,x"))
- (zero_extend:V16HI
- (match_operand:V16QI 2 "nonimmediate_operand" "xm,xm")))
- (const_vector:V16QI [(const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)]))
- (const_int 1))))]
- "TARGET_SSE2 && ix86_binary_operator_ok (PLUS, V16QImode, operands)"
- "@
- pavgb\t{%2, %0|%0, %2}
- vpavgb\t{%2, %1, %0|%0, %1, %2}"
- [(set_attr "isa" "noavx,avx")
- (set_attr "type" "sseiadd")
- (set_attr "prefix_data16" "1,*")
- (set_attr "prefix" "orig,vex")
- (set_attr "mode" "TI")])
-
-(define_expand "avx2_uavgv16hi3"
- [(set (match_operand:V16HI 0 "register_operand")
- (truncate:V16HI
- (lshiftrt:V16SI
- (plus:V16SI
- (plus:V16SI
- (zero_extend:V16SI
- (match_operand:V16HI 1 "nonimmediate_operand"))
- (zero_extend:V16SI
- (match_operand:V16HI 2 "nonimmediate_operand")))
- (const_vector:V16HI [(const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)]))
- (const_int 1))))]
- "TARGET_AVX2"
- "ix86_fixup_binary_operands_no_copy (PLUS, V16HImode, operands);")
-
-(define_expand "sse2_uavgv8hi3"
- [(set (match_operand:V8HI 0 "register_operand")
- (truncate:V8HI
- (lshiftrt:V8SI
- (plus:V8SI
- (plus:V8SI
- (zero_extend:V8SI
- (match_operand:V8HI 1 "nonimmediate_operand"))
- (zero_extend:V8SI
- (match_operand:V8HI 2 "nonimmediate_operand")))
- (const_vector:V8HI [(const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)]))
+(define_expand "<sse2_avx2>_uavg<mode>3"
+ [(set (match_operand:VI12_AVX2 0 "register_operand")
+ (truncate:VI12_AVX2
+ (lshiftrt:<ssedoublemode>
+ (plus:<ssedoublemode>
+ (plus:<ssedoublemode>
+ (zero_extend:<ssedoublemode>
+ (match_operand:VI12_AVX2 1 "nonimmediate_operand"))
+ (zero_extend:<ssedoublemode>
+ (match_operand:VI12_AVX2 2 "nonimmediate_operand")))
+ (match_dup 3))
(const_int 1))))]
"TARGET_SSE2"
- "ix86_fixup_binary_operands_no_copy (PLUS, V8HImode, operands);")
-
-(define_insn "*avx2_uavgv16hi3"
- [(set (match_operand:V16HI 0 "register_operand" "=x")
- (truncate:V16HI
- (lshiftrt:V16SI
- (plus:V16SI
- (plus:V16SI
- (zero_extend:V16SI
- (match_operand:V16HI 1 "nonimmediate_operand" "%x"))
- (zero_extend:V16SI
- (match_operand:V16HI 2 "nonimmediate_operand" "xm")))
- (const_vector:V16HI [(const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)]))
- (const_int 1))))]
- "TARGET_AVX2 && ix86_binary_operator_ok (PLUS, V16HImode, operands)"
- "vpavgw\t{%2, %1, %0|%0, %1, %2}"
- [(set_attr "type" "sseiadd")
- (set_attr "prefix" "vex")
- (set_attr "mode" "OI")])
+{
+ operands[3] = CONST1_RTX(<MODE>mode);
+ ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
+})
-(define_insn "*sse2_uavgv8hi3"
- [(set (match_operand:V8HI 0 "register_operand" "=x,x")
- (truncate:V8HI
- (lshiftrt:V8SI
- (plus:V8SI
- (plus:V8SI
- (zero_extend:V8SI
- (match_operand:V8HI 1 "nonimmediate_operand" "%0,x"))
- (zero_extend:V8SI
- (match_operand:V8HI 2 "nonimmediate_operand" "xm,xm")))
- (const_vector:V8HI [(const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)]))
+(define_insn "*<sse2_avx2>_uavg<mode>3"
+ [(set (match_operand:VI12_AVX2 0 "register_operand" "=x,x")
+ (truncate:VI12_AVX2
+ (lshiftrt:<ssedoublemode>
+ (plus:<ssedoublemode>
+ (plus:<ssedoublemode>
+ (zero_extend:<ssedoublemode>
+ (match_operand:VI12_AVX2 1 "nonimmediate_operand" "%0,x"))
+ (zero_extend:<ssedoublemode>
+ (match_operand:VI12_AVX2 2 "nonimmediate_operand" "xm,xm")))
+ (match_operand:VI12_AVX2 3 "const1_operand"))
(const_int 1))))]
- "TARGET_SSE2 && ix86_binary_operator_ok (PLUS, V8HImode, operands)"
+ "TARGET_SSE2 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
"@
- pavgw\t{%2, %0|%0, %2}
- vpavgw\t{%2, %1, %0|%0, %1, %2}"
+ pavg<ssemodesuffix>\t{%2, %0|%0, %2}
+ vpavg<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "isa" "noavx,avx")
(set_attr "type" "sseiadd")
(set_attr "prefix_data16" "1,*")
(set_attr "prefix" "orig,vex")
- (set_attr "mode" "TI")])
+ (set_attr "mode" "<sseinsnmode>")])
;; The correct representation for this is absolutely enormous, and
;; surely not generally useful.
@@ -8366,31 +8203,30 @@
(set (attr "prefix_rex") (symbol_ref "x86_extended_reg_mentioned_p (insn)"))
(set_attr "mode" "DI")])
-(define_expand "avx2_umulhrswv16hi3"
- [(set (match_operand:V16HI 0 "register_operand")
- (truncate:V16HI
- (lshiftrt:V16SI
- (plus:V16SI
- (lshiftrt:V16SI
- (mult:V16SI
- (sign_extend:V16SI
- (match_operand:V16HI 1 "nonimmediate_operand"))
- (sign_extend:V16SI
- (match_operand:V16HI 2 "nonimmediate_operand")))
+(define_mode_iterator PMULHRSW
+ [V4HI V8HI (V16HI "TARGET_AVX2")])
+
+(define_expand "<ssse3_avx2>_pmulhrsw<mode>3"
+ [(set (match_operand:PMULHRSW 0 "register_operand")
+ (truncate:PMULHRSW
+ (lshiftrt:<ssedoublemode>
+ (plus:<ssedoublemode>
+ (lshiftrt:<ssedoublemode>
+ (mult:<ssedoublemode>
+ (sign_extend:<ssedoublemode>
+ (match_operand:PMULHRSW 1 "nonimmediate_operand"))
+ (sign_extend:<ssedoublemode>
+ (match_operand:PMULHRSW 2 "nonimmediate_operand")))
(const_int 14))
- (const_vector:V16HI [(const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)]))
+ (match_dup 3))
(const_int 1))))]
"TARGET_AVX2"
- "ix86_fixup_binary_operands_no_copy (MULT, V16HImode, operands);")
+{
+ operands[3] = CONST1_RTX(<MODE>mode);
+ ix86_fixup_binary_operands_no_copy (MULT, <MODE>mode, operands);
+})
-(define_insn "*avx2_umulhrswv16hi3"
+(define_insn "*avx2_pmulhrswv16hi3"
[(set (match_operand:V16HI 0 "register_operand" "=x")
(truncate:V16HI
(lshiftrt:V16SI
@@ -8402,14 +8238,7 @@
(sign_extend:V16SI
(match_operand:V16HI 2 "nonimmediate_operand" "xm")))
(const_int 14))
- (const_vector:V16HI [(const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)]))
+ (match_operand:V16HI 3 "const1_operand"))
(const_int 1))))]
"TARGET_AVX2 && ix86_binary_operator_ok (MULT, V16HImode, operands)"
"vpmulhrsw\t{%2, %1, %0|%0, %1, %2}"
@@ -8418,26 +8247,6 @@
(set_attr "prefix" "vex")
(set_attr "mode" "OI")])
-(define_expand "ssse3_pmulhrswv8hi3"
- [(set (match_operand:V8HI 0 "register_operand")
- (truncate:V8HI
- (lshiftrt:V8SI
- (plus:V8SI
- (lshiftrt:V8SI
- (mult:V8SI
- (sign_extend:V8SI
- (match_operand:V8HI 1 "nonimmediate_operand"))
- (sign_extend:V8SI
- (match_operand:V8HI 2 "nonimmediate_operand")))
- (const_int 14))
- (const_vector:V8HI [(const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)]))
- (const_int 1))))]
- "TARGET_SSSE3"
- "ix86_fixup_binary_operands_no_copy (MULT, V8HImode, operands);")
-
(define_insn "*ssse3_pmulhrswv8hi3"
[(set (match_operand:V8HI 0 "register_operand" "=x,x")
(truncate:V8HI
@@ -8450,10 +8259,7 @@
(sign_extend:V8SI
(match_operand:V8HI 2 "nonimmediate_operand" "xm,xm")))
(const_int 14))
- (const_vector:V8HI [(const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)]))
+ (match_operand:V8HI 3 "const1_operand"))
(const_int 1))))]
"TARGET_SSSE3 && ix86_binary_operator_ok (MULT, V8HImode, operands)"
"@
@@ -8466,24 +8272,6 @@
(set_attr "prefix" "orig,vex")
(set_attr "mode" "TI")])
-(define_expand "ssse3_pmulhrswv4hi3"
- [(set (match_operand:V4HI 0 "register_operand")
- (truncate:V4HI
- (lshiftrt:V4SI
- (plus:V4SI
- (lshiftrt:V4SI
- (mult:V4SI
- (sign_extend:V4SI
- (match_operand:V4HI 1 "nonimmediate_operand"))
- (sign_extend:V4SI
- (match_operand:V4HI 2 "nonimmediate_operand")))
- (const_int 14))
- (const_vector:V4HI [(const_int 1) (const_int 1)
- (const_int 1) (const_int 1)]))
- (const_int 1))))]
- "TARGET_SSSE3"
- "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
-
(define_insn "*ssse3_pmulhrswv4hi3"
[(set (match_operand:V4HI 0 "register_operand" "=y")
(truncate:V4HI
@@ -8496,8 +8284,7 @@
(sign_extend:V4SI
(match_operand:V4HI 2 "nonimmediate_operand" "ym")))
(const_int 14))
- (const_vector:V4HI [(const_int 1) (const_int 1)
- (const_int 1) (const_int 1)]))
+ (match_operand:V4HI 3 "const1_operand"))
(const_int 1))))]
"TARGET_SSSE3 && ix86_binary_operator_ok (MULT, V4HImode, operands)"
"pmulhrsw\t{%2, %0|%0, %2}"
@@ -10665,8 +10452,7 @@
;; Clear the upper 128bits of AVX registers, equivalent to a NOP
;; if the upper 128bits are unused.
(define_insn "avx_vzeroupper"
- [(unspec_volatile [(match_operand 0 "const_int_operand")]
- UNSPECV_VZEROUPPER)]
+ [(unspec_volatile [(const_int 0)] UNSPECV_VZEROUPPER)]
"TARGET_AVX"
"vzeroupper"
[(set_attr "type" "sse")
diff --git a/gcc/config/i386/sync.md b/gcc/config/i386/sync.md
index 44cb5d4c070..d8555717f3d 100644
--- a/gcc/config/i386/sync.md
+++ b/gcc/config/i386/sync.md
@@ -149,9 +149,7 @@
if (<MODE>mode == DImode && !TARGET_64BIT)
emit_insn (gen_atomic_loaddi_fpu
(operands[0], operands[1],
- assign_386_stack_local (DImode,
- (virtuals_instantiated
- ? SLOT_TEMP : SLOT_VIRTUAL))));
+ assign_386_stack_local (DImode, SLOT_TEMP)));
else
emit_move_insn (operands[0], operands[1]);
DONE;
@@ -212,9 +210,7 @@
out to be significantly larger than this plus a barrier. */
emit_insn (gen_atomic_storedi_fpu
(operands[0], operands[1],
- assign_386_stack_local (DImode,
- (virtuals_instantiated
- ? SLOT_TEMP : SLOT_VIRTUAL))));
+ assign_386_stack_local (DImode, SLOT_TEMP)));
}
else
{
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index 1826a854c6e..ae671a29a85 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -3224,14 +3224,18 @@ shiftcosts (rtx x)
static inline int
and_xor_ior_costs (rtx x, int code)
{
- int i;
+ /* On SH1-4 we have only max. SImode operations.
+ Double the cost for modes > SImode. */
+ const int cost_scale = !TARGET_SHMEDIA
+ && GET_MODE_SIZE (GET_MODE (x)) > UNITS_PER_WORD
+ ? 2 : 1;
/* A logical operation with two registers is a single cycle
instruction. */
if (!CONST_INT_P (XEXP (x, 1)))
- return 1;
+ return 1 * cost_scale;
- i = INTVAL (XEXP (x, 1));
+ int i = INTVAL (XEXP (x, 1));
if (TARGET_SHMEDIA)
{
@@ -3244,19 +3248,19 @@ and_xor_ior_costs (rtx x, int code)
/* These constants are single cycle extu.[bw] instructions. */
if ((i == 0xff || i == 0xffff) && code == AND)
- return 1;
+ return 1 * cost_scale;
/* Constants that can be used in an instruction as an immediate are
a single cycle, but this requires r0, so make it a little more
expensive. */
if (CONST_OK_FOR_K08 (i))
- return 2;
+ return 2 * cost_scale;
/* Constants that can be loaded with a mov immediate need one more cycle.
This case is probably unnecessary. */
if (CONST_OK_FOR_I08 (i))
- return 2;
+ return 2 * cost_scale;
/* Any other constant requires an additional 2 cycle pc-relative load.
This case is probably unnecessary. */
- return 3;
+ return 3 * cost_scale;
}
/* Return the cost of an addition or a subtraction. */
@@ -3264,15 +3268,21 @@ and_xor_ior_costs (rtx x, int code)
static inline int
addsubcosts (rtx x)
{
+ /* On SH1-4 we have only max. SImode operations.
+ Double the cost for modes > SImode. */
+ const int cost_scale = !TARGET_SHMEDIA
+ && GET_MODE_SIZE (GET_MODE (x)) > UNITS_PER_WORD
+ ? 2 : 1;
+
/* Adding a register is a single cycle insn. */
if (REG_P (XEXP (x, 1))
|| GET_CODE (XEXP (x, 1)) == SUBREG)
- return 1;
+ return 1 * cost_scale;
/* Likewise for small constants. */
if (CONST_INT_P (XEXP (x, 1))
&& CONST_OK_FOR_ADD (INTVAL (XEXP (x, 1))))
- return 1;
+ return 1 * cost_scale;
if (TARGET_SHMEDIA)
switch (GET_CODE (XEXP (x, 1)))
@@ -3297,7 +3307,7 @@ addsubcosts (rtx x)
/* Any other constant requires a 2 cycle pc-relative load plus an
addition. */
- return 3;
+ return 3 * cost_scale;
}
/* Return the cost of a multiply. */
diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md
index a002304845e..3c9226523d7 100644
--- a/gcc/config/sh/sh.md
+++ b/gcc/config/sh/sh.md
@@ -4006,10 +4006,11 @@ label:
FAIL;
})
-;; The rotcr insn is used primarily in DImode right shifts (arithmetic
-;; and logical). It can also be used to implement things like
+;; The rotcr and rotcl insns are used primarily in DImode shifts by one.
+;; They can also be used to implement things like
;; bool t = a == b;
-;; int x = (y >> 1) | (t << 31);
+;; int x0 = (y >> 1) | (t << 31); // rotcr
+;; int x1 = (y << 1) | t; // rotcl
(define_insn "rotcr"
[(set (match_operand:SI 0 "arith_reg_dest" "=r")
(ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
@@ -4022,6 +4023,17 @@ label:
"rotcr %0"
[(set_attr "type" "arith")])
+(define_insn "rotcl"
+ [(set (match_operand:SI 0 "arith_reg_dest" "=r")
+ (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
+ (const_int 1))
+ (match_operand:SI 2 "t_reg_operand")))
+ (set (reg:SI T_REG)
+ (lshiftrt:SI (match_dup 1) (const_int 31)))]
+ "TARGET_SH1"
+ "rotcl %0"
+ [(set_attr "type" "arith")])
+
;; Simplified rotcr version for combine, which allows arbitrary shift
;; amounts for the reg. If the shift amount is '1' rotcr can be used
;; directly. Otherwise we have to insert a shift in between.
@@ -4121,6 +4133,160 @@ label:
(ashift:SI (match_dup 1) (const_int 31))))
(clobber (reg:SI T_REG))])])
+;; Basically the same as the rotcr pattern above, but for rotcl.
+;; FIXME: Fold copy pasted split code for rotcr and rotcl.
+(define_insn_and_split "*rotcl"
+ [(set (match_operand:SI 0 "arith_reg_dest")
+ (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand")
+ (match_operand:SI 2 "const_int_operand"))
+ (and:SI (match_operand:SI 3 "arith_reg_or_t_reg_operand")
+ (const_int 1))))
+ (clobber (reg:SI T_REG))]
+ "TARGET_SH1"
+ "#"
+ "&& can_create_pseudo_p ()"
+ [(const_int 0)]
+{
+ gcc_assert (INTVAL (operands[2]) > 0);
+
+ if (INTVAL (operands[2]) > 1)
+ {
+ const rtx shift_count = GEN_INT (INTVAL (operands[2]) - 1);
+ rtx prev_set_t_insn = NULL_RTX;
+ rtx tmp_t_reg = NULL_RTX;
+
+ /* If we're going to emit a shift sequence that clobbers the T_REG,
+ try to find the previous insn that sets the T_REG and emit the
+ shift insn before that insn, to remove the T_REG dependency.
+ If the insn that sets the T_REG cannot be found, store the T_REG
+ in a temporary reg and restore it after the shift. */
+ if (sh_ashlsi_clobbers_t_reg_p (shift_count)
+ && ! sh_dynamicalize_shift_p (shift_count))
+ {
+ prev_set_t_insn = prev_nonnote_insn_bb (curr_insn);
+
+ /* Skip the nott insn, which was probably inserted by the splitter
+ of *rotcl_neg_t. Don't use one of the recog functions
+ here during insn splitting, since that causes problems in later
+ passes. */
+ if (prev_set_t_insn != NULL_RTX)
+ {
+ rtx pat = PATTERN (prev_set_t_insn);
+ if (GET_CODE (pat) == SET
+ && t_reg_operand (XEXP (pat, 0), SImode)
+ && negt_reg_operand (XEXP (pat, 1), SImode))
+ prev_set_t_insn = prev_nonnote_insn_bb (prev_set_t_insn);
+ }
+
+ if (! (prev_set_t_insn != NULL_RTX
+ && reg_set_p (get_t_reg_rtx (), prev_set_t_insn)
+ && ! reg_referenced_p (get_t_reg_rtx (),
+ PATTERN (prev_set_t_insn))))
+ {
+ prev_set_t_insn = NULL_RTX;
+ tmp_t_reg = gen_reg_rtx (SImode);
+ emit_insn (gen_move_insn (tmp_t_reg, get_t_reg_rtx ()));
+ }
+ }
+
+ rtx shift_result = gen_reg_rtx (SImode);
+ rtx shift_insn = gen_ashlsi3 (shift_result, operands[1], shift_count);
+ operands[1] = shift_result;
+
+ /* Emit the shift insn before the insn that sets T_REG, if possible. */
+ if (prev_set_t_insn != NULL_RTX)
+ emit_insn_before (shift_insn, prev_set_t_insn);
+ else
+ emit_insn (shift_insn);
+
+ /* Restore T_REG if it has been saved before. */
+ if (tmp_t_reg != NULL_RTX)
+ emit_insn (gen_cmpgtsi_t (tmp_t_reg, const0_rtx));
+ }
+
+ /* For the rotcl insn to work, operands[3] must be in T_REG.
+ If it is not we can get it there by shifting it right one bit.
+ In this case T_REG is not an input for this insn, thus we don't have to
+ pay attention as of where to insert the shlr insn. */
+ if (! t_reg_operand (operands[3], SImode))
+ {
+ /* We don't care about the shifted result here, only the T_REG. */
+ emit_insn (gen_shlr (gen_reg_rtx (SImode), operands[3]));
+ operands[3] = get_t_reg_rtx ();
+ }
+
+ emit_insn (gen_rotcl (operands[0], operands[1], operands[3]));
+ DONE;
+})
+
+;; rotcl combine pattern variations
+(define_insn_and_split "*rotcl"
+ [(set (match_operand:SI 0 "arith_reg_dest")
+ (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand")
+ (match_operand:SI 2 "const_int_operand"))
+ (match_operand:SI 3 "t_reg_operand")))
+ (clobber (reg:SI T_REG))]
+ "TARGET_SH1"
+ "#"
+ "&& can_create_pseudo_p ()"
+ [(parallel [(set (match_dup 0)
+ (ior:SI (ashift:SI (match_dup 1) (match_dup 2))
+ (and:SI (match_dup 3) (const_int 1))))
+ (clobber (reg:SI T_REG))])])
+
+(define_insn_and_split "*rotcl"
+ [(set (match_operand:SI 0 "arith_reg_dest")
+ (ior:SI (and:SI (match_operand:SI 1 "arith_reg_or_t_reg_operand")
+ (const_int 1))
+ (ashift:SI (match_operand:SI 2 "arith_reg_operand")
+ (match_operand:SI 3 "const_int_operand"))))
+ (clobber (reg:SI T_REG))]
+ "TARGET_SH1"
+ "#"
+ "&& can_create_pseudo_p ()"
+ [(parallel [(set (match_dup 0)
+ (ior:SI (ashift:SI (match_dup 2) (match_dup 3))
+ (and:SI (match_dup 1) (const_int 1))))
+ (clobber (reg:SI T_REG))])])
+
+(define_insn_and_split "*rotcl"
+ [(set (match_operand:SI 0 "arith_reg_dest")
+ (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand")
+ (match_operand:SI 2 "const_int_operand"))
+ (lshiftrt:SI (match_operand:SI 3 "arith_reg_operand")
+ (const_int 31))))
+ (clobber (reg:SI T_REG))]
+ "TARGET_SH1"
+ "#"
+ "&& can_create_pseudo_p ()"
+ [(parallel [(set (match_dup 0)
+ (ior:SI (ashift:SI (match_dup 1) (match_dup 2))
+ (and:SI (reg:SI T_REG) (const_int 1))))
+ (clobber (reg:SI T_REG))])]
+{
+ /* We don't care about the result of the left shift, only the T_REG. */
+ emit_insn (gen_shll (gen_reg_rtx (SImode), operands[3]));
+})
+
+(define_insn_and_split "*rotcl"
+ [(set (match_operand:SI 0 "arith_reg_dest")
+ (ior:SI (lshiftrt:SI (match_operand:SI 3 "arith_reg_operand")
+ (const_int 31))
+ (ashift:SI (match_operand:SI 1 "arith_reg_operand")
+ (match_operand:SI 2 "const_int_operand"))))
+ (clobber (reg:SI T_REG))]
+ "TARGET_SH1"
+ "#"
+ "&& can_create_pseudo_p ()"
+ [(parallel [(set (match_dup 0)
+ (ior:SI (ashift:SI (match_dup 1) (match_dup 2))
+ (and:SI (reg:SI T_REG) (const_int 1))))
+ (clobber (reg:SI T_REG))])]
+{
+ /* We don't care about the result of the left shift, only the T_REG. */
+ emit_insn (gen_shll (gen_reg_rtx (SImode), operands[3]));
+})
+
;; rotcr combine bridge pattern which will make combine try out more
;; complex patterns.
(define_insn_and_split "*rotcr"
@@ -4189,6 +4355,35 @@ label:
emit_insn (gen_nott (get_t_reg_rtx ()));
})
+;; rotcl combine patterns for rotating in the negated T_REG value.
+;; For some strange reason these have to be specified as splits which combine
+;; will pick up. If they are specified as insn_and_split like the
+;; *rotcr_neg_t patterns above, combine would recognize them successfully
+;; but not emit them on non-SH2A targets.
+(define_split
+ [(set (match_operand:SI 0 "arith_reg_dest")
+ (ior:SI (match_operand:SI 1 "negt_reg_operand")
+ (ashift:SI (match_operand:SI 2 "arith_reg_operand")
+ (match_operand:SI 3 "const_int_operand"))))]
+ "TARGET_SH1"
+ [(set (reg:SI T_REG) (xor:SI (reg:SI T_REG) (const_int 1)))
+ (parallel [(set (match_dup 0)
+ (ior:SI (ashift:SI (match_dup 2) (match_dup 3))
+ (and:SI (reg:SI T_REG) (const_int 1))))
+ (clobber (reg:SI T_REG))])])
+
+(define_split
+ [(set (match_operand:SI 0 "arith_reg_dest")
+ (ior:SI (ashift:SI (match_operand:SI 2 "arith_reg_operand")
+ (match_operand:SI 3 "const_int_operand"))
+ (match_operand:SI 1 "negt_reg_operand")))]
+ "TARGET_SH1"
+ [(set (reg:SI T_REG) (xor:SI (reg:SI T_REG) (const_int 1)))
+ (parallel [(set (match_dup 0)
+ (ior:SI (ashift:SI (match_dup 2) (match_dup 3))
+ (and:SI (reg:SI T_REG) (const_int 1))))
+ (clobber (reg:SI T_REG))])])
+
;; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
;; SImode shift left
@@ -4480,16 +4675,22 @@ label:
DONE;
})
-;; This should be an define_insn_and_split.
-(define_insn "ashldi3_k"
+(define_insn_and_split "ashldi3_k"
[(set (match_operand:DI 0 "arith_reg_dest" "=r")
(ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
(const_int 1)))
(clobber (reg:SI T_REG))]
"TARGET_SH1"
- "shll %R0\;rotcl %S0"
- [(set_attr "length" "4")
- (set_attr "type" "arith")])
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+{
+ rtx high = gen_highpart (SImode, operands[0]);
+ rtx low = gen_lowpart (SImode, operands[0]);
+ emit_insn (gen_shll (low, low));
+ emit_insn (gen_rotcl (high, high, get_t_reg_rtx ()));
+ DONE;
+})
(define_insn "ashldi3_media"
[(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index cc4db401af8..5e73e1bc0c7 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,22 @@
+2012-11-05 Sriraman Tallam <tmsriram@google.com>
+
+ * class.c (add_method): Change assembler names of function versions.
+ (mark_versions_used): New static function.
+ (resolve_address_of_overloaded_function): Create dispatcher decl and
+ return address of dispatcher instead.
+ * decl.c (decls_match): Make decls unmatched for versioned
+ functions.
+ (duplicate_decls): Remove ambiguity for versioned functions.
+ Delete versioned function data for merged decls.
+ * decl2.c (check_classfn): Check attributes of versioned functions
+ for match.
+ * call.c (get_function_version_dispatcher): New function.
+ (mark_versions_used): New static function.
+ (build_over_call): Make calls to multiversioned functions
+ to call the dispatcher.
+ (joust): For calls to multi-versioned functions, make the most
+ specialized function version win.
+
2012-10-31 Lawrence Crowl <crowl@google.com>
* decl2.c (var_finalized_p): Rename varpool_node to
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index fcc973505be..4373bce6931 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -40,6 +40,7 @@ along with GCC; see the file COPYING3. If not see
#include "langhooks.h"
#include "c-family/c-objc.h"
#include "timevar.h"
+#include "cgraph.h"
/* The various kinds of conversion. */
@@ -6514,6 +6515,63 @@ magic_varargs_p (tree fn)
return false;
}
+/* Returns the decl of the dispatcher function if FN is a function version. */
+
+static tree
+get_function_version_dispatcher (tree fn)
+{
+ tree dispatcher_decl = NULL;
+
+ gcc_assert (TREE_CODE (fn) == FUNCTION_DECL
+ && DECL_FUNCTION_VERSIONED (fn));
+
+ gcc_assert (targetm.get_function_versions_dispatcher);
+ dispatcher_decl = targetm.get_function_versions_dispatcher (fn);
+
+ if (dispatcher_decl == NULL)
+ {
+ error_at (input_location, "Call to multiversioned function"
+ " without a default is not allowed");
+ return NULL;
+ }
+
+ retrofit_lang_decl (dispatcher_decl);
+ gcc_assert (dispatcher_decl != NULL);
+ return dispatcher_decl;
+}
+
+/* fn is a function version dispatcher that is marked used. Mark all the
+ semantically identical function versions it will dispatch as used. */
+
+static void
+mark_versions_used (tree fn)
+{
+ struct cgraph_node *node;
+ struct cgraph_function_version_info *node_v;
+ struct cgraph_function_version_info *it_v;
+
+ gcc_assert (TREE_CODE (fn) == FUNCTION_DECL);
+
+ node = cgraph_get_node (fn);
+ if (node == NULL)
+ return;
+
+ gcc_assert (node->dispatcher_function);
+
+ node_v = get_cgraph_node_version (node);
+ if (node_v == NULL)
+ return;
+
+ /* All semantically identical versions are chained. Traverse and mark each
+ one of them as used. */
+ it_v = node_v->next;
+ while (it_v != NULL)
+ {
+ mark_used (it_v->this_node->symbol.decl);
+ it_v = it_v->next;
+ }
+}
+
/* Subroutine of the various build_*_call functions. Overload resolution
has chosen a winning candidate CAND; build up a CALL_EXPR accordingly.
ARGS is a TREE_LIST of the unconverted arguments to the call. FLAGS is a
@@ -6963,6 +7021,22 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
return fold_convert (void_type_node, argarray[0]);
/* FIXME handle trivial default constructor, too. */
+ /* For calls to a multi-versioned function, overload resolution
+ returns the function with the highest target priority, that is,
+ the version that will checked for dispatching first. If this
+ version is inlinable, a direct call to this version can be made
+ otherwise the call should go through the dispatcher. */
+
+ if (DECL_FUNCTION_VERSIONED (fn)
+ && !targetm.target_option.can_inline_p (current_function_decl, fn))
+ {
+ fn = get_function_version_dispatcher (fn);
+ if (fn == NULL)
+ return NULL;
+ if (!already_used)
+ mark_versions_used (fn);
+ }
+
if (!already_used)
mark_used (fn);
@@ -8481,6 +8555,38 @@ joust (struct z_candidate *cand1, struct z_candidate *cand2, bool warn,
}
}
+ /* For candidates of a multi-versioned function, make the version with
+ the highest priority win. This version will be checked for dispatching
+ first. If this version can be inlined into the caller, the front-end
+ will simply make a direct call to this function. */
+
+ if (TREE_CODE (cand1->fn) == FUNCTION_DECL
+ && DECL_FUNCTION_VERSIONED (cand1->fn)
+ && TREE_CODE (cand2->fn) == FUNCTION_DECL
+ && DECL_FUNCTION_VERSIONED (cand2->fn))
+ {
+ tree f1 = TREE_TYPE (cand1->fn);
+ tree f2 = TREE_TYPE (cand2->fn);
+ tree p1 = TYPE_ARG_TYPES (f1);
+ tree p2 = TYPE_ARG_TYPES (f2);
+
+ /* Check if cand1->fn and cand2->fn are versions of the same function. It
+ is possible that cand1->fn and cand2->fn are function versions but of
+ different functions. Check types to see if they are versions of the same
+ function. */
+ if (compparms (p1, p2)
+ && same_type_p (TREE_TYPE (f1), TREE_TYPE (f2)))
+ {
+ /* Always make the version with the higher priority, more
+ specialized, win. */
+ gcc_assert (targetm.compare_version_priority);
+ if (targetm.compare_version_priority (cand1->fn, cand2->fn) >= 0)
+ return 1;
+ else
+ return -1;
+ }
+ }
+
/* If the two function declarations represent the same function (this can
happen with declarations in multiple scopes and arg-dependent lookup),
arbitrarily choose one. But first make sure the default args we're
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index e55f1f9c2b7..a91e63a6301 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -1087,6 +1087,35 @@ add_method (tree type, tree method, tree using_decl)
|| same_type_p (TREE_TYPE (fn_type),
TREE_TYPE (method_type))))
{
+ /* For function versions, their parms and types match
+ but they are not duplicates. Record function versions
+ as and when they are found. extern "C" functions are
+ not treated as versions. */
+ if (TREE_CODE (fn) == FUNCTION_DECL
+ && TREE_CODE (method) == FUNCTION_DECL
+ && !DECL_EXTERN_C_P (fn)
+ && !DECL_EXTERN_C_P (method)
+ && (DECL_FUNCTION_SPECIFIC_TARGET (fn)
+ || DECL_FUNCTION_SPECIFIC_TARGET (method))
+ && targetm.target_option.function_versions (fn, method))
+ {
+ /* Mark functions as versions if necessary. Modify the mangled
+ decl name if necessary. */
+ if (!DECL_FUNCTION_VERSIONED (fn))
+ {
+ DECL_FUNCTION_VERSIONED (fn) = 1;
+ if (DECL_ASSEMBLER_NAME_SET_P (fn))
+ mangle_decl (fn);
+ }
+ if (!DECL_FUNCTION_VERSIONED (method))
+ {
+ DECL_FUNCTION_VERSIONED (method) = 1;
+ if (DECL_ASSEMBLER_NAME_SET_P (method))
+ mangle_decl (method);
+ }
+ record_function_versions (fn, method);
+ continue;
+ }
if (DECL_INHERITED_CTOR_BASE (method))
{
if (DECL_INHERITED_CTOR_BASE (fn))
@@ -6951,6 +6980,38 @@ pop_lang_context (void)
{
current_lang_name = VEC_pop (tree, current_lang_base);
}
+
+/* fn is a function version dispatcher that is marked used. Mark all the
+ semantically identical function versions it will dispatch as used. */
+
+static void
+mark_versions_used (tree fn)
+{
+ struct cgraph_node *node;
+ struct cgraph_function_version_info *node_v;
+ struct cgraph_function_version_info *it_v;
+
+ gcc_assert (TREE_CODE (fn) == FUNCTION_DECL);
+
+ node = cgraph_get_node (fn);
+ if (node == NULL)
+ return;
+
+ gcc_assert (node->dispatcher_function);
+
+ node_v = get_cgraph_node_version (node);
+ if (node_v == NULL)
+ return;
+
+ /* All semantically identical versions are chained. Traverse and mark each
+ one of them as used. */
+ it_v = node_v->next;
+ while (it_v != NULL)
+ {
+ mark_used (it_v->this_node->symbol.decl);
+ it_v = it_v->next;
+ }
+}
/* Type instantiation routines. */
@@ -7162,12 +7223,26 @@ resolve_address_of_overloaded_function (tree target_type,
{
/* There were too many matches. First check if they're all
the same function. */
- tree match;
+ tree match = NULL_TREE;
fn = TREE_PURPOSE (matches);
- for (match = TREE_CHAIN (matches); match; match = TREE_CHAIN (match))
- if (!decls_match (fn, TREE_PURPOSE (match)))
- break;
+
+ /* For multi-versioned functions, more than one match is just fine.
+ Call decls_match to make sure they are different because they are
+ versioned. */
+ if (DECL_FUNCTION_VERSIONED (fn))
+ {
+ for (match = TREE_CHAIN (matches); match; match = TREE_CHAIN (match))
+ if (!DECL_FUNCTION_VERSIONED (TREE_PURPOSE (match))
+ || decls_match (fn, TREE_PURPOSE (match)))
+ break;
+ }
+ else
+ {
+ for (match = TREE_CHAIN (matches); match; match = TREE_CHAIN (match))
+ if (!decls_match (fn, TREE_PURPOSE (match)))
+ break;
+ }
if (match)
{
@@ -7208,6 +7283,28 @@ resolve_address_of_overloaded_function (tree target_type,
}
}
+ /* If a pointer to a function that is multi-versioned is requested, the
+ pointer to the dispatcher function is returned instead. This works
+ well because indirectly calling the function will dispatch the right
+ function version at run-time. */
+ if (DECL_FUNCTION_VERSIONED (fn))
+ {
+ tree dispatcher_decl = NULL;
+ gcc_assert (targetm.get_function_versions_dispatcher);
+ dispatcher_decl = targetm.get_function_versions_dispatcher (fn);
+ if (!dispatcher_decl)
+ {
+ error_at (input_location, "Pointer to a multiversioned function"
+ " without a default is not allowed");
+ return error_mark_node;
+ }
+ retrofit_lang_decl (dispatcher_decl);
+ fn = dispatcher_decl;
+ /* Mark all the versions corresponding to the dispatcher as used. */
+ if (!(flags & tf_conv))
+ mark_versions_used (fn);
+ }
+
/* If we're doing overload resolution purely for the purpose of
determining conversion sequences, we should not consider the
function used. If this conversion sequence is selected, the
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index d25aa804971..f8f9d4f2391 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -53,6 +53,7 @@ along with GCC; see the file COPYING3. If not see
#include "pointer-set.h"
#include "splay-tree.h"
#include "plugin.h"
+#include "cgraph.h"
/* Possible cases of bad specifiers type used by bad_specifiers. */
enum bad_spec_place {
@@ -981,6 +982,36 @@ decls_match (tree newdecl, tree olddecl)
if (t1 != t2)
return 0;
+ /* The decls dont match if they correspond to two different versions
+ of the same function. Disallow extern "C" functions to be
+ versions for now. */
+ if (compparms (p1, p2)
+ && same_type_p (TREE_TYPE (f1), TREE_TYPE (f2))
+ && !DECL_EXTERN_C_P (newdecl)
+ && !DECL_EXTERN_C_P (olddecl)
+ && targetm.target_option.function_versions (newdecl, olddecl))
+ {
+ /* Mark functions as versions if necessary. Modify the mangled decl
+ name if necessary. */
+ if (DECL_FUNCTION_VERSIONED (newdecl)
+ && DECL_FUNCTION_VERSIONED (olddecl))
+ return 0;
+ if (!DECL_FUNCTION_VERSIONED (newdecl))
+ {
+ DECL_FUNCTION_VERSIONED (newdecl) = 1;
+ if (DECL_ASSEMBLER_NAME_SET_P (newdecl))
+ mangle_decl (newdecl);
+ }
+ if (!DECL_FUNCTION_VERSIONED (olddecl))
+ {
+ DECL_FUNCTION_VERSIONED (olddecl) = 1;
+ if (DECL_ASSEMBLER_NAME_SET_P (olddecl))
+ mangle_decl (olddecl);
+ }
+ record_function_versions (olddecl, newdecl);
+ return 0;
+ }
+
if (CP_DECL_CONTEXT (newdecl) != CP_DECL_CONTEXT (olddecl)
&& ! (DECL_EXTERN_C_P (newdecl)
&& DECL_EXTERN_C_P (olddecl)))
@@ -1499,7 +1530,11 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
error ("previous declaration %q+#D here", olddecl);
return NULL_TREE;
}
- else if (compparms (TYPE_ARG_TYPES (TREE_TYPE (newdecl)),
+ /* For function versions, params and types match, but they
+ are not ambiguous. */
+ else if ((!DECL_FUNCTION_VERSIONED (newdecl)
+ && !DECL_FUNCTION_VERSIONED (olddecl))
+ && compparms (TYPE_ARG_TYPES (TREE_TYPE (newdecl)),
TYPE_ARG_TYPES (TREE_TYPE (olddecl))))
{
error ("new declaration %q#D", newdecl);
@@ -2272,6 +2307,15 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
else if (DECL_PRESERVE_P (newdecl))
DECL_PRESERVE_P (olddecl) = 1;
+ /* If the olddecl is a version, so is the newdecl. */
+ if (TREE_CODE (newdecl) == FUNCTION_DECL
+ && DECL_FUNCTION_VERSIONED (olddecl))
+ {
+ DECL_FUNCTION_VERSIONED (newdecl) = 1;
+ /* newdecl will be purged and is no longer a version. */
+ delete_function_version (newdecl);
+ }
+
if (TREE_CODE (newdecl) == FUNCTION_DECL)
{
int function_size;
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index f3ce643e12e..90ee16bde96 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -674,9 +674,13 @@ check_classfn (tree ctype, tree function, tree template_parms)
if (is_template != (TREE_CODE (fndecl) == TEMPLATE_DECL))
continue;
+ /* While finding a match, same types and params are not enough
+ if the function is versioned. Also check version ("target")
+ attributes. */
if (same_type_p (TREE_TYPE (TREE_TYPE (function)),
TREE_TYPE (TREE_TYPE (fndecl)))
&& compparms (p1, p2)
+ && !targetm.target_option.function_versions (function, fndecl)
&& (!is_template
|| comp_template_parms (template_parms,
DECL_TEMPLATE_PARMS (fndecl)))
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 1338e6e461c..73363a1a5a6 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -9085,6 +9085,9 @@ the loop code is peeled.
@item max-peel-times
The maximum number of peelings of a single loop.
+@item max-peel-branches
+The maximum number of branches on the hot path through the peeled sequence.
+
@item max-completely-peeled-insns
The maximum number of insns of a completely peeled loop.
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 665c5b1edd6..dbf6c20b8dd 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -9929,6 +9929,14 @@ changed via the optimize attribute or pragma, see
@code{TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE}
@end deftypefn
+@deftypefn {Target Hook} bool TARGET_OPTION_FUNCTION_VERSIONS (tree @var{decl1}, tree @var{decl2})
+This target hook returns @code{true} if @var{DECL1} and @var{DECL2} are
+versions of the same function. @var{DECL1} and @var{DECL2} are function
+versions if and only if they have the same function signature and
+different target specific attributes, that is, they are compiled for
+different target machines.
+@end deftypefn
+
@deftypefn {Target Hook} bool TARGET_CAN_INLINE_P (tree @var{caller}, tree @var{callee})
This target hook returns @code{false} if the @var{caller} function
cannot inline @var{callee}, based on target specific information. By
@@ -10952,6 +10960,29 @@ The result is another tree containing a simplified expression for the
call's result. If @var{ignore} is true the value will be ignored.
@end deftypefn
+@deftypefn {Target Hook} int TARGET_COMPARE_VERSION_PRIORITY (tree @var{decl1}, tree @var{decl2})
+This hook is used to compare the target attributes in two functions to
+determine which function's features get higher priority. This is used
+during function multi-versioning to figure out the order in which two
+versions must be dispatched. A function version with a higher priority
+is checked for dispatching earlier. @var{decl1} and @var{decl2} are
+ the two function decls that will be compared.
+@end deftypefn
+
+@deftypefn {Target Hook} tree TARGET_GET_FUNCTION_VERSIONS_DISPATCHER (void *@var{decl})
+This hook is used to get the dispatcher function for a set of function
+versions. The dispatcher function is called to invoke the right function
+version at run-time. @var{decl} is one version from a set of semantically
+identical versions.
+@end deftypefn
+
+@deftypefn {Target Hook} tree TARGET_GENERATE_VERSION_DISPATCHER_BODY (void *@var{arg})
+This hook is used to generate the dispatcher logic to invoke the right
+function version at run-time for a given set of function versions.
+@var{arg} points to the callgraph node of the dispatcher function whose
+body must be generated.
+@end deftypefn
+
@deftypefn {Target Hook} {const char *} TARGET_INVALID_WITHIN_DOLOOP (const_rtx @var{insn})
Take an instruction in @var{insn} and return NULL if it is valid within a
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index 289934be17e..575cc7322af 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -9790,6 +9790,14 @@ changed via the optimize attribute or pragma, see
@code{TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE}
@end deftypefn
+@hook TARGET_OPTION_FUNCTION_VERSIONS
+This target hook returns @code{true} if @var{DECL1} and @var{DECL2} are
+versions of the same function. @var{DECL1} and @var{DECL2} are function
+versions if and only if they have the same function signature and
+different target specific attributes, that is, they are compiled for
+different target machines.
+@end deftypefn
+
@hook TARGET_CAN_INLINE_P
This target hook returns @code{false} if the @var{caller} function
cannot inline @var{callee}, based on target specific information. By
@@ -10798,6 +10806,29 @@ The result is another tree containing a simplified expression for the
call's result. If @var{ignore} is true the value will be ignored.
@end deftypefn
+@hook TARGET_COMPARE_VERSION_PRIORITY
+This hook is used to compare the target attributes in two functions to
+determine which function's features get higher priority. This is used
+during function multi-versioning to figure out the order in which two
+versions must be dispatched. A function version with a higher priority
+is checked for dispatching earlier. @var{decl1} and @var{decl2} are
+ the two function decls that will be compared.
+@end deftypefn
+
+@hook TARGET_GET_FUNCTION_VERSIONS_DISPATCHER
+This hook is used to get the dispatcher function for a set of function
+versions. The dispatcher function is called to invoke the right function
+version at run-time. @var{decl} is one version from a set of semantically
+identical versions.
+@end deftypefn
+
+@hook TARGET_GENERATE_VERSION_DISPATCHER_BODY
+This hook is used to generate the dispatcher logic to invoke the right
+function version at run-time for a given set of function versions.
+@var{arg} points to the callgraph node of the dispatcher function whose
+body must be generated.
+@end deftypefn
+
@hook TARGET_INVALID_WITHIN_DOLOOP
Take an instruction in @var{insn} and return NULL if it is valid within a
diff --git a/gcc/final.c b/gcc/final.c
index f69963d6335..fc10dd6d5a6 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -1,7 +1,7 @@
/* Convert RTL to assembler code and output it, for GNU compiler.
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997,
1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
- 2010, 2011
+ 2010, 2011, 2012
Free Software Foundation, Inc.
This file is part of GCC.
@@ -2689,36 +2689,19 @@ final_scan_insn (rtx insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
else_rtx = const0_rtx;
}
- switch (GET_CODE (cond_rtx))
+ if (COMPARISON_P (cond_rtx)
+ && XEXP (cond_rtx, 0) == cc0_rtx)
{
- case GTU:
- case GT:
- case LTU:
- case LT:
- case GEU:
- case GE:
- case LEU:
- case LE:
- case EQ:
- case NE:
- {
- int result;
- if (XEXP (cond_rtx, 0) != cc0_rtx)
- break;
- result = alter_cond (cond_rtx);
- if (result == 1)
- validate_change (insn, &SET_SRC (set), then_rtx, 0);
- else if (result == -1)
- validate_change (insn, &SET_SRC (set), else_rtx, 0);
- else if (result == 2)
- INSN_CODE (insn) = -1;
- if (SET_DEST (set) == SET_SRC (set))
- delete_insn (insn);
- }
- break;
-
- default:
- break;
+ int result;
+ result = alter_cond (cond_rtx);
+ if (result == 1)
+ validate_change (insn, &SET_SRC (set), then_rtx, 0);
+ else if (result == -1)
+ validate_change (insn, &SET_SRC (set), else_rtx, 0);
+ else if (result == 2)
+ INSN_CODE (insn) = -1;
+ if (SET_DEST (set) == SET_SRC (set))
+ delete_insn (insn);
}
}
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 084f1f8c53b..f33dffb0f64 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,11 @@
+2012-11-06 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/54917
+ * target-memory.c (gfc_target_expr_size,gfc_target_interpret_expr):
+ Handle BT_CLASS.
+ * trans-intrinsic.c (gfc_conv_intrinsic_transfer): Add support for
+ polymorphic arguments.
+
2012-11-04 Janus Weil <janus@gcc.gnu.org>
PR fortran/55199
diff --git a/gcc/fortran/target-memory.c b/gcc/fortran/target-memory.c
index aec7fa207bd..437a3df8304 100644
--- a/gcc/fortran/target-memory.c
+++ b/gcc/fortran/target-memory.c
@@ -121,6 +121,7 @@ gfc_target_expr_size (gfc_expr *e)
case BT_HOLLERITH:
return e->representation.length;
case BT_DERIVED:
+ case BT_CLASS:
{
/* Determine type size without clobbering the typespec for ISO C
binding types. */
@@ -572,6 +573,9 @@ gfc_target_interpret_expr (unsigned char *buffer, size_t buffer_size,
gfc_interpret_character (buffer, buffer_size, result);
break;
+ case BT_CLASS:
+ result->ts = CLASS_DATA (result)->ts;
+ /* Fall through. */
case BT_DERIVED:
result->representation.length =
gfc_interpret_derived (buffer, buffer_size, result);
diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c
index 4b268b34ba7..b101cb46728 100644
--- a/gcc/fortran/trans-intrinsic.c
+++ b/gcc/fortran/trans-intrinsic.c
@@ -5348,6 +5348,7 @@ gfc_conv_intrinsic_transfer (gfc_se * se, gfc_expr * expr)
stmtblock_t block;
int n;
bool scalar_mold;
+ gfc_expr *source_expr, *mold_expr;
info = NULL;
if (se->loop)
@@ -5357,6 +5358,7 @@ gfc_conv_intrinsic_transfer (gfc_se * se, gfc_expr * expr)
source_bytes = length of the source in bytes
source = pointer to the source data. */
arg = expr->value.function.actual;
+ source_expr = arg->expr;
/* Ensure double transfer through LOGICAL preserves all
the needed bits. */
@@ -5376,18 +5378,28 @@ gfc_conv_intrinsic_transfer (gfc_se * se, gfc_expr * expr)
if (arg->expr->rank == 0)
{
gfc_conv_expr_reference (&argse, arg->expr);
- source = argse.expr;
-
- source_type = TREE_TYPE (build_fold_indirect_ref_loc (input_location,
- argse.expr));
+ if (arg->expr->ts.type == BT_CLASS)
+ source = gfc_class_data_get (argse.expr);
+ else
+ source = argse.expr;
/* Obtain the source word length. */
- if (arg->expr->ts.type == BT_CHARACTER)
- tmp = size_of_string_in_bytes (arg->expr->ts.kind,
- argse.string_length);
- else
- tmp = fold_convert (gfc_array_index_type,
- size_in_bytes (source_type));
+ switch (arg->expr->ts.type)
+ {
+ case BT_CHARACTER:
+ tmp = size_of_string_in_bytes (arg->expr->ts.kind,
+ argse.string_length);
+ break;
+ case BT_CLASS:
+ tmp = gfc_vtable_size_get (argse.expr);
+ break;
+ default:
+ source_type = TREE_TYPE (build_fold_indirect_ref_loc (input_location,
+ source));
+ tmp = fold_convert (gfc_array_index_type,
+ size_in_bytes (source_type));
+ break;
+ }
}
else
{
@@ -5464,6 +5476,7 @@ gfc_conv_intrinsic_transfer (gfc_se * se, gfc_expr * expr)
mold_type = the TREE type of MOLD
dest_word_len = destination word length in bytes. */
arg = arg->next;
+ mold_expr = arg->expr;
gfc_init_se (&argse, NULL);
@@ -5473,7 +5486,7 @@ gfc_conv_intrinsic_transfer (gfc_se * se, gfc_expr * expr)
{
gfc_conv_expr_reference (&argse, arg->expr);
mold_type = TREE_TYPE (build_fold_indirect_ref_loc (input_location,
- argse.expr));
+ argse.expr));
}
else
{
@@ -5494,15 +5507,20 @@ gfc_conv_intrinsic_transfer (gfc_se * se, gfc_expr * expr)
mold_type = gfc_get_int_type (arg->expr->ts.kind);
}
- if (arg->expr->ts.type == BT_CHARACTER)
+ /* Obtain the destination word length. */
+ switch (arg->expr->ts.type)
{
+ case BT_CHARACTER:
tmp = size_of_string_in_bytes (arg->expr->ts.kind, argse.string_length);
mold_type = gfc_get_character_type_len (arg->expr->ts.kind, tmp);
+ break;
+ case BT_CLASS:
+ tmp = gfc_vtable_size_get (argse.expr);
+ break;
+ default:
+ tmp = fold_convert (gfc_array_index_type, size_in_bytes (mold_type));
+ break;
}
- else
- tmp = fold_convert (gfc_array_index_type,
- size_in_bytes (mold_type));
-
dest_word_len = gfc_create_var (gfc_array_index_type, NULL);
gfc_add_modify (&se->pre, dest_word_len, tmp);
@@ -5650,8 +5668,21 @@ scalar_transfer:
ptr = convert (build_pointer_type (mold_type), source);
+ /* For CLASS results, allocate the needed memory first. */
+ if (mold_expr->ts.type == BT_CLASS)
+ {
+ tree cdata;
+ cdata = gfc_class_data_get (tmpdecl);
+ tmp = gfc_call_malloc (&se->pre, TREE_TYPE (cdata), dest_word_len);
+ gfc_add_modify (&se->pre, cdata, tmp);
+ }
+
/* Use memcpy to do the transfer. */
- tmp = gfc_build_addr_expr (NULL_TREE, tmpdecl);
+ if (mold_expr->ts.type == BT_CLASS)
+ tmp = gfc_class_data_get (tmpdecl);
+ else
+ tmp = gfc_build_addr_expr (NULL_TREE, tmpdecl);
+
tmp = build_call_expr_loc (input_location,
builtin_decl_explicit (BUILT_IN_MEMCPY), 3,
fold_convert (pvoid_type_node, tmp),
@@ -5659,6 +5690,18 @@ scalar_transfer:
extent);
gfc_add_expr_to_block (&se->pre, tmp);
+ /* For CLASS results, set the _vptr. */
+ if (mold_expr->ts.type == BT_CLASS)
+ {
+ tree vptr;
+ gfc_symbol *vtab;
+ vptr = gfc_class_vptr_get (tmpdecl);
+ vtab = gfc_find_derived_vtab (source_expr->ts.u.derived);
+ gcc_assert (vtab);
+ tmp = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtab));
+ gfc_add_modify (&se->pre, vptr, fold_convert (TREE_TYPE (vptr), tmp));
+ }
+
se->expr = tmpdecl;
}
}
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index 66d076664cc..969cfeb5829 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -139,7 +139,8 @@ can_refer_decl_in_current_unit_p (tree decl, tree from_decl)
tree
canonicalize_constructor_val (tree cval, tree from_decl)
{
- STRIP_USELESS_TYPE_CONVERSION (cval);
+ tree orig_cval = cval;
+ STRIP_NOPS (cval);
if (TREE_CODE (cval) == POINTER_PLUS_EXPR
&& TREE_CODE (TREE_OPERAND (cval, 1)) == INTEGER_CST)
{
@@ -182,8 +183,12 @@ canonicalize_constructor_val (tree cval, tree from_decl)
/* Fixup types in global initializers. */
if (TREE_TYPE (TREE_TYPE (cval)) != TREE_TYPE (TREE_OPERAND (cval, 0)))
cval = build_fold_addr_expr (TREE_OPERAND (cval, 0));
+
+ if (!useless_type_conversion_p (TREE_TYPE (orig_cval), TREE_TYPE (cval)))
+ cval = fold_convert (TREE_TYPE (orig_cval), cval);
+ return cval;
}
- return cval;
+ return orig_cval;
}
/* If SYM is a constant variable with known value, return the value.
diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c
index b6a69cbbc7c..4b705799855 100644
--- a/gcc/ipa-inline.c
+++ b/gcc/ipa-inline.c
@@ -459,16 +459,16 @@ want_early_inline_function_p (struct cgraph_edge *e)
/* Compute time of the edge->caller + edge->callee execution when inlining
does not happen. */
-inline int
+inline gcov_type
compute_uninlined_call_time (struct inline_summary *callee_info,
struct cgraph_edge *edge)
{
- int uninlined_call_time =
+ gcov_type uninlined_call_time =
RDIV ((gcov_type)callee_info->time * MAX (edge->frequency, 1),
CGRAPH_FREQ_BASE);
- int caller_time = inline_summary (edge->caller->global.inlined_to
- ? edge->caller->global.inlined_to
- : edge->caller)->time;
+ gcov_type caller_time = inline_summary (edge->caller->global.inlined_to
+ ? edge->caller->global.inlined_to
+ : edge->caller)->time;
return uninlined_call_time + caller_time;
}
@@ -479,12 +479,13 @@ inline gcov_type
compute_inlined_call_time (struct cgraph_edge *edge,
int edge_time)
{
- int caller_time = inline_summary (edge->caller->global.inlined_to
- ? edge->caller->global.inlined_to
- : edge->caller)->time;
- int time = caller_time + RDIV ((edge_time - inline_edge_summary (edge)->call_stmt_time)
- * MAX (edge->frequency, 1),
- CGRAPH_FREQ_BASE);
+ gcov_type caller_time = inline_summary (edge->caller->global.inlined_to
+ ? edge->caller->global.inlined_to
+ : edge->caller)->time;
+ gcov_type time = (caller_time
+ + RDIV (((gcov_type) edge_time
+ - inline_edge_summary (edge)->call_stmt_time)
+ * MAX (edge->frequency, 1), CGRAPH_FREQ_BASE));
/* Possible one roundoff error, but watch for overflows. */
gcc_checking_assert (time >= INT_MIN / 2);
if (time < 0)
@@ -770,9 +771,9 @@ relative_time_benefit (struct inline_summary *callee_info,
struct cgraph_edge *edge,
int edge_time)
{
- int relbenefit;
- int uninlined_call_time = compute_uninlined_call_time (callee_info, edge);
- int inlined_call_time = compute_inlined_call_time (edge, edge_time);
+ gcov_type relbenefit;
+ gcov_type uninlined_call_time = compute_uninlined_call_time (callee_info, edge);
+ gcov_type inlined_call_time = compute_inlined_call_time (edge, edge_time);
/* Inlining into extern inline function is not a win. */
if (DECL_EXTERNAL (edge->caller->global.inlined_to
@@ -918,7 +919,7 @@ edge_badness (struct cgraph_edge *edge, bool dump)
(int) badness, (double)edge->frequency / CGRAPH_FREQ_BASE,
relative_time_benefit (callee_info, edge, edge_time) * 100.0
/ RELATIVE_TIME_BENEFIT_RANGE,
- compute_uninlined_call_time (callee_info, edge),
+ (int)compute_uninlined_call_time (callee_info, edge),
(int)compute_inlined_call_time (edge, edge_time),
estimate_growth (callee),
callee_info->growth);
diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c
index 58f9e5a11da..5cf974b7b37 100644
--- a/gcc/ipa-pure-const.c
+++ b/gcc/ipa-pure-const.c
@@ -671,15 +671,18 @@ check_stmt (gimple_stmt_iterator *gsip, funct_state local, bool ipa)
if (cfun->can_throw_non_call_exceptions)
{
if (dump_file)
- fprintf (dump_file, " can throw; looping");
+ fprintf (dump_file, " can throw; looping\n");
local->looping = true;
}
if (stmt_can_throw_external (stmt))
{
if (dump_file)
- fprintf (dump_file, " can throw externally");
+ fprintf (dump_file, " can throw externally\n");
local->can_throw = true;
}
+ else
+ if (dump_file)
+ fprintf (dump_file, " can throw\n");
}
switch (gimple_code (stmt))
{
@@ -691,7 +694,7 @@ check_stmt (gimple_stmt_iterator *gsip, funct_state local, bool ipa)
/* Target of long jump. */
{
if (dump_file)
- fprintf (dump_file, " nonlocal label is not const/pure");
+ fprintf (dump_file, " nonlocal label is not const/pure\n");
local->pure_const_state = IPA_NEITHER;
}
break;
@@ -699,14 +702,14 @@ check_stmt (gimple_stmt_iterator *gsip, funct_state local, bool ipa)
if (gimple_asm_clobbers_memory_p (stmt))
{
if (dump_file)
- fprintf (dump_file, " memory asm clobber is not const/pure");
+ fprintf (dump_file, " memory asm clobber is not const/pure\n");
/* Abandon all hope, ye who enter here. */
local->pure_const_state = IPA_NEITHER;
}
if (gimple_asm_volatile_p (stmt))
{
if (dump_file)
- fprintf (dump_file, " volatile is not const/pure");
+ fprintf (dump_file, " volatile is not const/pure\n");
/* Abandon all hope, ye who enter here. */
local->pure_const_state = IPA_NEITHER;
local->looping = true;
diff --git a/gcc/mode-switching.c b/gcc/mode-switching.c
index d9f83ca2a3b..386f8d1abe9 100644
--- a/gcc/mode-switching.c
+++ b/gcc/mode-switching.c
@@ -1,6 +1,6 @@
/* CPU mode switching
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008,
- 2009, 2010 Free Software Foundation, Inc.
+ 2009, 2010, 2012 Free Software Foundation, Inc.
This file is part of GCC.
@@ -324,7 +324,10 @@ create_pre_exit (int n_entities, int *entity_map, const int *num_modes)
else
break;
if (copy_start >= FIRST_PSEUDO_REGISTER)
- break;
+ {
+ last_insn = return_copy;
+ continue;
+ }
copy_num
= hard_regno_nregs[copy_start][GET_MODE (copy_reg)];
@@ -342,6 +345,16 @@ create_pre_exit (int n_entities, int *entity_map, const int *num_modes)
}
if (j >= 0)
{
+ /* __builtin_return emits a sequence of loads to all
+ return registers. One of them might require
+ another mode than MODE_EXIT, even if it is
+ unrelated to the return value, so we want to put
+ the final mode switch after it. */
+ if (maybe_builtin_apply
+ && targetm.calls.function_value_regno_p
+ (copy_start))
+ forced_late_switch = 1;
+
/* For the SH4, floating point loads depend on fpscr,
thus we might need to put the final mode switch
after the return value copy. That is still OK,
diff --git a/gcc/params.def b/gcc/params.def
index 8733f1ba631..0ceb8a26263 100644
--- a/gcc/params.def
+++ b/gcc/params.def
@@ -291,6 +291,11 @@ DEFPARAM(PARAM_MAX_PEEL_TIMES,
"max-peel-times",
"The maximum number of peelings of a single loop",
16, 0, 0)
+/* The maximum number of peelings of a single loop that is peeled completely. */
+DEFPARAM(PARAM_MAX_PEEL_BRANCHES,
+ "max-peel-branches",
+ "The maximum number of branches on the path through the peeled sequence",
+ 32, 0, 0)
/* The maximum number of insns of a peeled loop. */
DEFPARAM(PARAM_MAX_COMPLETELY_PEELED_INSNS,
"max-completely-peeled-insns",
diff --git a/gcc/recog.c b/gcc/recog.c
index 8206f5eace9..3a534551345 100644
--- a/gcc/recog.c
+++ b/gcc/recog.c
@@ -2165,7 +2165,7 @@ extract_insn (rtx insn)
{
which_alternative = i;
recog_data.alternative_enabled_p[i]
- = HAVE_ATTR_enabled ? get_attr_enabled (insn) : 0;
+ = HAVE_ATTR_enabled ? get_attr_enabled (insn) : 1;
}
}
diff --git a/gcc/target.def b/gcc/target.def
index 586522435a2..2801aea5a17 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -1298,6 +1298,37 @@ DEFHOOK
tree, (tree fndecl, int n_args, tree *argp, bool ignore),
hook_tree_tree_int_treep_bool_null)
+/* Target hook is used to compare the target attributes in two functions to
+ determine which function's features get higher priority. This is used
+ during function multi-versioning to figure out the order in which two
+ versions must be dispatched. A function version with a higher priority
+ is checked for dispatching earlier. DECL1 and DECL2 are
+ the two function decls that will be compared. It returns positive value
+ if DECL1 is higher priority, negative value if DECL2 is higher priority
+ and 0 if they are the same. */
+DEFHOOK
+(compare_version_priority,
+ "",
+ int, (tree decl1, tree decl2), NULL)
+
+/* Target hook is used to generate the dispatcher logic to invoke the right
+ function version at run-time for a given set of function versions.
+ ARG points to the callgraph node of the dispatcher function whose body
+ must be generated. */
+DEFHOOK
+(generate_version_dispatcher_body,
+ "",
+ tree, (void *arg), NULL)
+
+/* Target hook is used to get the dispatcher function for a set of function
+ versions. The dispatcher function is called to invoke the right function
+ version at run-time. DECL is one version from a set of semantically
+ identical versions. */
+DEFHOOK
+(get_function_versions_dispatcher,
+ "",
+ tree, (void *decl), NULL)
+
/* Returns a code for a target-specific builtin that implements
reciprocal of the function, or NULL_TREE if not available. */
DEFHOOK
@@ -2774,6 +2805,16 @@ DEFHOOK
void, (void),
hook_void_void)
+/* This function returns true if DECL1 and DECL2 are versions of the same
+ function. DECL1 and DECL2 are function versions if and only if they
+ have the same function signature and different target specific attributes,
+ that is, they are compiled for different target machines. */
+DEFHOOK
+(function_versions,
+ "",
+ bool, (tree decl1, tree decl2),
+ hook_bool_tree_tree_false)
+
/* Function to determine if one function can inline another function. */
#undef HOOK_PREFIX
#define HOOK_PREFIX "TARGET_"
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 4d6a7dcc42c..be75f5374fd 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,74 @@
+2012-11-06 Jan Hubicka <jh@suse.cz>
+
+ * gcc.dg/tree-ssa/loop-1.c: Make to look like a good unroling candidate still.
+ * gcc.dg/tree-ssa/loop-23.c: Likewise.
+ * gcc.dg/tree-ssa/cunroll-1.c: Unrolling now happens early.
+ * gcc.dg/tree-prof/unroll-1.c: Remove confused dg-options.
+
+2012-11-06 David Edelsohn <dje.gcc@gmail.com>
+
+ * const-uniq-1.c: Expand regex to match AIX XCOFF labels.
+
+2012-11-06 Uros Bizjak <ubizjak@gmail.com>
+
+ PR middle-end/41993
+ * gcc.dg/torture/pr41993.c: New test.
+
+2012-11-06 Jan Hubicka <jh@suse.cz>
+
+ * gcc.target/i386/l_fma_float_?.c: Update.
+ * gcc.target/i386/l_fma_double_?.c: Update.
+
+2012-11-06 Oleg Endo <olegendo@gcc.gnu.org>
+
+ PR target/54089
+ * gcc.target/sh/pr54089-8.c: New.
+ * gcc.target/sh/pr54089-9.c: New.
+
+2012-11-06 Vladimir Yakovlev <vladimir.b.yakovlev@intel.com>
+
+ * gcc.target/i386/avx-vzeroupper-5.c: Changed scan-assembler-times.
+ * gcc.target/i386/avx-vzeroupper-8.c: Likewise.
+ * gcc.target/i386/avx-vzeroupper-9.c: Likewise.
+ * gcc.target/i386/avx-vzeroupper-10.c: Likewise.
+ * gcc.target/i386/avx-vzeroupper-11.c: Likewise.
+ * gcc.target/i386/avx-vzeroupper-12.c: Likewise.
+ * gcc.target/i386/avx-vzeroupper-19.c: Likewis.
+ * gcc.target/i386/avx-vzeroupper-27.c: New.
+
+2012-11-06 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/54917
+ * gfortran.dg/transfer_class_1.f90: New.
+ * gfortran.dg/transfer_class_2.f90: New.
+
+2012-11-05 Sriraman Tallam <tmsriram@google.com>
+
+ * testsuite/g++.dg/mv1.C: New test.
+ * testsuite/g++.dg/mv2.C: New test.
+ * testsuite/g++.dg/mv3.C: New test.
+ * testsuite/g++.dg/mv4.C: New test.
+ * testsuite/g++.dg/mv5.C: New test.
+ * testsuite/g++.dg/mv6.C: New test.
+
+2012-11-05 Hans-Peter Nilsson <hp@axis.com>
+
+ PR testsuite/55186
+ * gcc.dg/const-uniq-1.c (a): Increase length four times.
+
+2012-11-05 Jack Howarth <howarth@bromo.med.uc.edu>
+
+ * gcc.dg/torture/pr53922.c: Use -Wl,-undefined,dynamic_lookup on
+ darwin.
+
+2012-11-05 Eric Botcazou <ebotcazou@adacore.com>
+
+ * g++.dg/torture/20121105-1.C: New test.
+
+2012-11-05 Andreas Schwab <schwab@linux-m68k.org>
+
+ * gcc.dg/torture/fp-compare.c: New testcase.
+
2012-11-05 Jan Hubicka <jh@suse.cz>
* gcc.dg/const-1.c: Update.
diff --git a/gcc/testsuite/g++.dg/mv1.C b/gcc/testsuite/g++.dg/mv1.C
new file mode 100644
index 00000000000..676e48577af
--- /dev/null
+++ b/gcc/testsuite/g++.dg/mv1.C
@@ -0,0 +1,130 @@
+/* Test case to check if Multiversioning works. */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-ifunc "" } */
+/* { dg-options "-O2 -fPIC -mno-avx -mno-popcnt" } */
+
+#include <assert.h>
+
+/* Default version. */
+int foo ();
+/* The other versions of foo. Mix up the ordering and
+ check if the dispatching does it in the order of priority. */
+/* Check combination of target attributes. */
+int foo () __attribute__ ((target("arch=corei7,popcnt")));
+/* The target operands in this declaration and the definition are re-ordered.
+ This should still work. */
+int foo () __attribute__ ((target("ssse3,avx2")));
+
+/* Check for all target attributes for which dispatchers are available. */
+/* Check arch= */
+int foo () __attribute__((target("arch=core2")));
+int foo () __attribute__((target("arch=corei7")));
+int foo () __attribute__((target("arch=atom")));
+/* Check ISAs */
+int foo () __attribute__((target("avx")));
+int foo () __attribute__ ((target("arch=core2,sse4.2")));
+/* Check more arch=. */
+int foo () __attribute__((target("arch=amdfam10")));
+int foo () __attribute__((target("arch=bdver1")));
+int foo () __attribute__((target("arch=bdver2")));
+
+int (*p)() = &foo;
+int main ()
+{
+ int val = foo ();
+ assert (val == (*p)());
+
+ /* Check in the exact same order in which the dispatching
+ is expected to happen. */
+ if (__builtin_cpu_is ("bdver1"))
+ assert (val == 1);
+ else if (__builtin_cpu_is ("bdver2"))
+ assert (val == 2);
+ else if (__builtin_cpu_supports ("avx2")
+ && __builtin_cpu_supports ("ssse3"))
+ assert (val == 3);
+ else if (__builtin_cpu_supports ("avx"))
+ assert (val == 4);
+ else if (__builtin_cpu_is ("corei7")
+ && __builtin_cpu_supports ("popcnt"))
+ assert (val == 5);
+ else if (__builtin_cpu_is ("corei7"))
+ assert (val == 6);
+ else if (__builtin_cpu_is ("amdfam10h"))
+ assert (val == 7);
+ else if (__builtin_cpu_is ("core2")
+ && __builtin_cpu_supports ("sse4.2"))
+ assert (val == 8);
+ else if (__builtin_cpu_is ("core2"))
+ assert (val == 9);
+ else if (__builtin_cpu_is ("atom"))
+ assert (val == 10);
+ else
+ assert (val == 0);
+
+ return 0;
+}
+
+int foo ()
+{
+ return 0;
+}
+
+int __attribute__ ((target("arch=corei7,popcnt")))
+foo ()
+{
+ return 5;
+}
+int __attribute__ ((target("avx2,ssse3")))
+foo ()
+{
+ return 3;
+}
+
+int __attribute__ ((target("arch=core2")))
+foo ()
+{
+ return 9;
+}
+
+int __attribute__ ((target("arch=corei7")))
+foo ()
+{
+ return 6;
+}
+
+int __attribute__ ((target("arch=atom")))
+foo ()
+{
+ return 10;
+}
+
+int __attribute__ ((target("avx")))
+foo ()
+{
+ return 4;
+}
+
+int __attribute__ ((target("arch=core2,sse4.2")))
+foo ()
+{
+ return 8;
+}
+
+int __attribute__ ((target("arch=amdfam10")))
+foo ()
+{
+ return 7;
+}
+
+int __attribute__ ((target("arch=bdver1")))
+foo ()
+{
+ return 1;
+}
+
+int __attribute__ ((target("arch=bdver2")))
+foo ()
+{
+ return 2;
+}
diff --git a/gcc/testsuite/g++.dg/mv2.C b/gcc/testsuite/g++.dg/mv2.C
new file mode 100644
index 00000000000..f94877a674f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/mv2.C
@@ -0,0 +1,118 @@
+/* Test case to check if Multiversioning chooses the correct
+ dispatching order when versions are for various ISAs. */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-ifunc "" } */
+/* { dg-options "-O2 -mno-sse -mno-mmx -mno-popcnt -mno-avx" } */
+
+#include <assert.h>
+
+/* Default version. */
+int foo ();
+/* The dispatch checks should be in the exact reverse order of the
+ declarations below. */
+int foo () __attribute__ ((target ("mmx")));
+int foo () __attribute__ ((target ("sse")));
+int foo () __attribute__ ((target ("sse2")));
+int foo () __attribute__ ((target ("sse3")));
+int foo () __attribute__ ((target ("ssse3")));
+int foo () __attribute__ ((target ("sse4.1")));
+int foo () __attribute__ ((target ("sse4.2")));
+int foo () __attribute__ ((target ("popcnt")));
+int foo () __attribute__ ((target ("avx")));
+int foo () __attribute__ ((target ("avx2")));
+
+int main ()
+{
+ int val = foo ();
+
+ if (__builtin_cpu_supports ("avx2"))
+ assert (val == 1);
+ else if (__builtin_cpu_supports ("avx"))
+ assert (val == 2);
+ else if (__builtin_cpu_supports ("popcnt"))
+ assert (val == 3);
+ else if (__builtin_cpu_supports ("sse4.2"))
+ assert (val == 4);
+ else if (__builtin_cpu_supports ("sse4.1"))
+ assert (val == 5);
+ else if (__builtin_cpu_supports ("ssse3"))
+ assert (val == 6);
+ else if (__builtin_cpu_supports ("sse3"))
+ assert (val == 7);
+ else if (__builtin_cpu_supports ("sse2"))
+ assert (val == 8);
+ else if (__builtin_cpu_supports ("sse"))
+ assert (val == 9);
+ else if (__builtin_cpu_supports ("mmx"))
+ assert (val == 10);
+ else
+ assert (val == 0);
+
+ return 0;
+}
+
+int
+foo ()
+{
+ return 0;
+}
+
+int __attribute__ ((target("mmx")))
+foo ()
+{
+ return 10;
+}
+
+int __attribute__ ((target("sse")))
+foo ()
+{
+ return 9;
+}
+
+int __attribute__ ((target("sse2")))
+foo ()
+{
+ return 8;
+}
+
+int __attribute__ ((target("sse3")))
+foo ()
+{
+ return 7;
+}
+
+int __attribute__ ((target("ssse3")))
+foo ()
+{
+ return 6;
+}
+
+int __attribute__ ((target("sse4.1")))
+foo ()
+{
+ return 5;
+}
+
+int __attribute__ ((target("sse4.2")))
+foo ()
+{
+ return 4;
+}
+
+int __attribute__ ((target("popcnt")))
+foo ()
+{
+ return 3;
+}
+
+int __attribute__ ((target("avx")))
+foo ()
+{
+ return 2;
+}
+
+int __attribute__ ((target("avx2")))
+foo ()
+{
+ return 1;
+}
diff --git a/gcc/testsuite/g++.dg/mv3.C b/gcc/testsuite/g++.dg/mv3.C
new file mode 100644
index 00000000000..c7088f2b013
--- /dev/null
+++ b/gcc/testsuite/g++.dg/mv3.C
@@ -0,0 +1,36 @@
+/* Test case to check if a call to a multiversioned function
+ is replaced with a direct call to the particular version when
+ the most specialized version's target attributes match the
+ caller.
+
+ In this program, foo is multiversioned but there is no default
+ function. This is an error if the call has to go through a
+ dispatcher. However, the call to foo in bar can be replaced
+ with a direct call to the popcnt version of foo. Hence, this
+ test should pass. */
+
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -mno-sse -mno-popcnt" } */
+
+
+int __attribute__ ((target ("sse")))
+foo ()
+{
+ return 1;
+}
+int __attribute__ ((target ("popcnt")))
+foo ()
+{
+ return 0;
+}
+
+int __attribute__ ((target ("popcnt")))
+bar ()
+{
+ return foo ();
+}
+
+int main ()
+{
+ return bar ();
+}
diff --git a/gcc/testsuite/g++.dg/mv4.C b/gcc/testsuite/g++.dg/mv4.C
new file mode 100644
index 00000000000..1a7290643ac
--- /dev/null
+++ b/gcc/testsuite/g++.dg/mv4.C
@@ -0,0 +1,23 @@
+/* Test case to check if the compiler generates an error message
+ when the default version of a multiversioned function is absent
+ and its pointer is taken. */
+
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -mno-sse -mno-popcnt" } */
+
+int __attribute__ ((target ("sse")))
+foo ()
+{
+ return 1;
+}
+int __attribute__ ((target ("popcnt")))
+foo ()
+{
+ return 0;
+}
+
+int main ()
+{
+ int (*p)() = &foo; /* { dg-error "Pointer to a multiversioned function without a default is not allowed" {} } */
+ return (*p)();
+}
diff --git a/gcc/testsuite/g++.dg/mv5.C b/gcc/testsuite/g++.dg/mv5.C
new file mode 100644
index 00000000000..33d72804bcf
--- /dev/null
+++ b/gcc/testsuite/g++.dg/mv5.C
@@ -0,0 +1,24 @@
+/* Test case to check if multiversioned functions are still generated if they are
+ marked comdat with inline keyword. */
+
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -mno-popcnt" } */
+
+
+/* Default version. */
+inline int
+foo ()
+{
+ return 0;
+}
+
+inline int __attribute__ ((target ("popcnt")))
+foo ()
+{
+ return 0;
+}
+
+int main ()
+{
+ return foo ();
+}
diff --git a/gcc/testsuite/g++.dg/mv6.C b/gcc/testsuite/g++.dg/mv6.C
new file mode 100644
index 00000000000..7e5aa29d0bb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/mv6.C
@@ -0,0 +1,25 @@
+/* Test to check if member version multiversioning works correctly. */
+
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+
+class Foo
+{
+ public:
+ /* Default version of foo. */
+ int foo ()
+ {
+ return 0;
+ }
+ /* corei7 version of foo. */
+ __attribute__ ((target("arch=corei7")))
+ int foo ()
+ {
+ return 0;
+ }
+};
+
+int main ()
+{
+ Foo f;
+ return f.foo ();
+}
diff --git a/gcc/testsuite/g++.dg/torture/20121105-1.C b/gcc/testsuite/g++.dg/torture/20121105-1.C
new file mode 100644
index 00000000000..03323421a5e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/20121105-1.C
@@ -0,0 +1,42 @@
+// PR tree-optimization/54986
+// Reported by Remi Vanicat <vanicat@debian.org>
+// Reduced testcase by Markus Trippelsdorf <markus@trippelsdorf.de>
+
+struct A;
+struct B
+{
+ int *_ptr;
+ bool operator==(B *p1)
+ {
+ return p1->_ptr;
+ }
+};
+struct C {
+ A* ref_SYMBptr();
+};
+struct A
+{
+ B sommet;
+};
+typedef C *gen_op_context;
+struct D
+{
+ D(gen_op_context) {}
+};
+
+D c(0);
+const long d = (long)&c;
+B *const e = (B *)&d;
+
+static bool
+fn1(C& p1)
+{
+ return p1.ref_SYMBptr()->sommet == e;
+}
+
+void
+fn2()
+{
+ C b;
+ fn1(b);
+}
diff --git a/gcc/testsuite/gcc.dg/const-uniq-1.c b/gcc/testsuite/gcc.dg/const-uniq-1.c
index 8172c678b24..497efed8a4f 100644
--- a/gcc/testsuite/gcc.dg/const-uniq-1.c
+++ b/gcc/testsuite/gcc.dg/const-uniq-1.c
@@ -5,15 +5,20 @@
int lookup1 (int i)
{
- int a[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
+ /* We use vectors long enough that piece-wise initialization is not
+ reasonably preferable even for size (when including the constant
+ vectors for initialization) for any target. */
+ int a[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 };
return a[i];
}
int lookup2 (int i)
{
- int a[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
+ int a[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 };
return a[i+1];
}
-/* { dg-final { scan-tree-dump-times "L\\\$?C0" 2 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "L\\\$?C\\\.*0" 2 "gimple" } } */
/* { dg-final { cleanup-tree-dump "gimple" } } */
diff --git a/gcc/testsuite/gcc.dg/torture/fp-compare.c b/gcc/testsuite/gcc.dg/torture/fp-compare.c
new file mode 100644
index 00000000000..0d51dfd2478
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/fp-compare.c
@@ -0,0 +1,23 @@
+/* { dg-do run } */
+/* Check that find_scan_insn properly handles swapped FP comparisons. */
+static double x;
+static int exit_code;
+
+void __attribute__ ((noinline))
+check_int (int a, int b)
+{
+ exit_code += (a != b);
+}
+
+int
+main (void)
+{
+ x = 0.0;
+ asm ("" : "+m" (x));
+ check_int (__builtin_isgreater (x, 1.0), 0);
+ check_int (__builtin_isgreaterequal (x, 1.0), 0);
+ check_int (__builtin_isless (x, 1.0), 1);
+ check_int (__builtin_islessequal (x, 1.0), 1);
+ check_int (__builtin_islessgreater (x, 1.0), 1);
+ return exit_code;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr41993.c b/gcc/testsuite/gcc.dg/torture/pr41993.c
new file mode 100644
index 00000000000..890e3656159
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr41993.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-options "-mavx -mvzeroupper" { target { i?86-*-* x86_64-*-* } } } */
+
+short retframe_short (void *rframe)
+{
+ __builtin_return (rframe);
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr53922.c b/gcc/testsuite/gcc.dg/torture/pr53922.c
index 57011e46cb5..5a0e9d1daff 100644
--- a/gcc/testsuite/gcc.dg/torture/pr53922.c
+++ b/gcc/testsuite/gcc.dg/torture/pr53922.c
@@ -1,6 +1,7 @@
/* { dg-do run } */
/* { dg-require-weak "" } */
/* { dg-skip-if "No undefined weak" { hppa*-*-hpux* && { ! lp64 } } { "*" } { "" } } */
+/* { dg-options "-Wl,-undefined,dynamic_lookup" { target *-*-darwin* } } */
int x(int a)
{
diff --git a/gcc/testsuite/gcc.dg/tree-prof/unroll-1.c b/gcc/testsuite/gcc.dg/tree-prof/unroll-1.c
index b1c6b8b2d39..0b6e2ea13a8 100644
--- a/gcc/testsuite/gcc.dg/tree-prof/unroll-1.c
+++ b/gcc/testsuite/gcc.dg/tree-prof/unroll-1.c
@@ -21,4 +21,3 @@ main()
}
/* { dg-final-use { scan-rtl-dump "Considering unrolling loop with constant number of iterations" "loop2_unroll" } } */
/* { dg-final-use { cleanup-rtl-dump "Not unrolling loop, doesn't roll" } } */
-/* { dg-options "-O3 -fdump-rtl-loop2_unroll -funroll-loops -fno-peel-loops" } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/cunroll-1.c b/gcc/testsuite/gcc.dg/tree-ssa/cunroll-1.c
index c302b17a86d..37d5ba10334 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/cunroll-1.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/cunroll-1.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O3 -fdump-tree-cunroll-details" } */
+/* { dg-options "-O3 -fdump-tree-cunrolli-details" } */
int a[2];
test(int c)
{
@@ -10,4 +10,4 @@ test(int c)
/* Array bounds says the loop will not roll much. */
/* { dg-final { scan-tree-dump "Unrolled loop 1 completely .duplicated 1 times.." "cunroll"} } */
/* { dg-final { scan-tree-dump "Last iteration exit edge was proved true." "cunroll"} } */
-/* { dg-final { cleanup-tree-dump "cunroll" } } */
+/* { dg-final { cleanup-tree-dump "cunrolli" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loop-1.c b/gcc/testsuite/gcc.dg/tree-ssa/loop-1.c
index e4ad7a9fa7e..35ff0be60fa 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/loop-1.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/loop-1.c
@@ -17,13 +17,16 @@
to the load from the GOT this also contains the name of the funtion so for
each call the function name would appear twice. */
/* { dg-options "-O1 -ftree-loop-ivcanon -funroll-loops -fdump-tree-ivcanon-details -fdump-tree-cunroll-details -fdump-tree-optimized -mno-relax-pic-calls" { target mips*-*-* } } */
-
-void xxx(void)
+__attribute__ ((pure))
+int foo (int x);
+int xxx(void)
{
int x = 45;
+ int sum;
while (x >>= 1)
- foo ();
+ sum += foo (x) * 2;
+ return sum;
}
/* We should be able to find out that the loop iterates four times and unroll it completely. */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loop-23.c b/gcc/testsuite/gcc.dg/tree-ssa/loop-23.c
index a16dc5f0357..466d1758d1f 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/loop-23.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/loop-23.c
@@ -1,24 +1,27 @@
/* { dg-do compile } */
/* { dg-options "-O2 -funroll-loops -fdump-tree-cunroll-details" } */
-void bla(int);
+__attribute__ ((pure))
+int bla(int);
-void foo(void)
+int foo(void)
{
int i;
+ int sum;
/* This loop used to appear to be too large for unrolling. */
for (i = 0; i < 4; i++)
{
- bla (i);
- bla (2*i);
- bla (3*i);
- bla (4*i);
- bla (5*i);
- bla (6*i);
- bla (7*i);
- bla (8*i);
+ sum += bla (i);
+ sum += bla (2*i);
+ sum += bla (3*i);
+ sum += bla (4*i);
+ sum += bla (5*i);
+ sum += bla (6*i);
+ sum += bla (7*i);
+ sum += bla (8*i);
}
+ return sum;
}
/* { dg-final { scan-tree-dump-times "Unrolled loop 1 completely" 1 "cunroll" } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx-vzeroupper-10.c b/gcc/testsuite/gcc.target/i386/avx-vzeroupper-10.c
index 667bb17180f..5007753a0b7 100644
--- a/gcc/testsuite/gcc.target/i386/avx-vzeroupper-10.c
+++ b/gcc/testsuite/gcc.target/i386/avx-vzeroupper-10.c
@@ -14,4 +14,4 @@ foo ()
_mm256_zeroupper ();
}
-/* { dg-final { scan-assembler-not "avx_vzeroupper" } } */
+/* { dg-final { scan-assembler-times "avx_vzeroupper" 3 } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx-vzeroupper-11.c b/gcc/testsuite/gcc.target/i386/avx-vzeroupper-11.c
index d98ceb92012..507f9454391 100644
--- a/gcc/testsuite/gcc.target/i386/avx-vzeroupper-11.c
+++ b/gcc/testsuite/gcc.target/i386/avx-vzeroupper-11.c
@@ -16,4 +16,4 @@ foo ()
}
/* { dg-final { scan-assembler-times "\\*avx_vzeroall" 1 } } */
-/* { dg-final { scan-assembler-not "avx_vzeroupper" } } */
+/* { dg-final { scan-assembler-times "avx_vzeroupper" 3 } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx-vzeroupper-12.c b/gcc/testsuite/gcc.target/i386/avx-vzeroupper-12.c
index f74ea0c2cd3..e694d4048bd 100644
--- a/gcc/testsuite/gcc.target/i386/avx-vzeroupper-12.c
+++ b/gcc/testsuite/gcc.target/i386/avx-vzeroupper-12.c
@@ -16,5 +16,5 @@ foo ()
_mm256_zeroupper ();
}
-/* { dg-final { scan-assembler-times "avx_vzeroupper" 1 } } */
+/* { dg-final { scan-assembler-times "avx_vzeroupper" 4 } } */
/* { dg-final { scan-assembler-times "\\*avx_vzeroall" 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx-vzeroupper-19.c b/gcc/testsuite/gcc.target/i386/avx-vzeroupper-19.c
index 602de87f545..ae2f8611ea6 100644
--- a/gcc/testsuite/gcc.target/i386/avx-vzeroupper-19.c
+++ b/gcc/testsuite/gcc.target/i386/avx-vzeroupper-19.c
@@ -14,4 +14,4 @@ void feat_s3_cep_dcep (int cepsize_used, float **mfc, float **feat)
f[i] = w[i] - _w[i];
}
-/* { dg-final { scan-assembler-times "avx_vzeroupper" 1 } } */
+/* { dg-final { scan-assembler-times "avx_vzeroupper" 2 } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx-vzeroupper-27.c b/gcc/testsuite/gcc.target/i386/avx-vzeroupper-27.c
new file mode 100644
index 00000000000..7fa5de43763
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx-vzeroupper-27.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mavx -mtune=generic -dp" } */
+
+typedef struct objc_class *Class;
+typedef struct objc_object
+{
+ Class class_pointer;
+} *id;
+
+typedef const struct objc_selector *SEL;
+typedef void * retval_t;
+typedef void * arglist_t;
+
+extern retval_t __objc_forward (id object, SEL sel, arglist_t args);
+
+double
+__objc_double_forward (id rcv, SEL op, ...)
+{
+ void *args, *res;
+
+ args = __builtin_apply_args ();
+ res = __objc_forward (rcv, op, args);
+ __builtin_return (res);
+}
+
+/* { dg-final { scan-assembler-times "avx_vzeroupper" 2 } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx-vzeroupper-5.c b/gcc/testsuite/gcc.target/i386/avx-vzeroupper-5.c
index 0f54602b8c8..ba08978ab4e 100644
--- a/gcc/testsuite/gcc.target/i386/avx-vzeroupper-5.c
+++ b/gcc/testsuite/gcc.target/i386/avx-vzeroupper-5.c
@@ -14,4 +14,4 @@ foo ()
_mm256_zeroupper ();
}
-/* { dg-final { scan-assembler-not "avx_vzeroupper" } } */
+/* { dg-final { scan-assembler-times "avx_vzeroupper" 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx-vzeroupper-8.c b/gcc/testsuite/gcc.target/i386/avx-vzeroupper-8.c
index 0a821c24a86..bb370c5b44e 100644
--- a/gcc/testsuite/gcc.target/i386/avx-vzeroupper-8.c
+++ b/gcc/testsuite/gcc.target/i386/avx-vzeroupper-8.c
@@ -13,4 +13,4 @@ foo ()
_mm256_zeroupper ();
}
-/* { dg-final { scan-assembler-not "avx_vzeroupper" } } */
+/* { dg-final { scan-assembler-times "avx_vzeroupper" 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx-vzeroupper-9.c b/gcc/testsuite/gcc.target/i386/avx-vzeroupper-9.c
index 5aa05b83902..974e1626a6d 100644
--- a/gcc/testsuite/gcc.target/i386/avx-vzeroupper-9.c
+++ b/gcc/testsuite/gcc.target/i386/avx-vzeroupper-9.c
@@ -15,4 +15,4 @@ foo ()
_mm256_zeroupper ();
}
-/* { dg-final { scan-assembler-times "avx_vzeroupper" 1 } } */
+/* { dg-final { scan-assembler-times "avx_vzeroupper" 4 } } */
diff --git a/gcc/testsuite/gcc.target/i386/l_fma_double_1.c b/gcc/testsuite/gcc.target/i386/l_fma_double_1.c
index 716acfef65c..270659359f4 100644
--- a/gcc/testsuite/gcc.target/i386/l_fma_double_1.c
+++ b/gcc/testsuite/gcc.target/i386/l_fma_double_1.c
@@ -16,11 +16,11 @@
/* { dg-final { scan-assembler-times "vfnmadd231pd" 4 } } */
/* { dg-final { scan-assembler-times "vfnmsub132pd" 4 } } */
/* { dg-final { scan-assembler-times "vfnmsub231pd" 4 } } */
-/* { dg-final { scan-assembler-times "vfmadd132sd" 20 } } */
-/* { dg-final { scan-assembler-times "vfmadd213sd" 20 } } */
-/* { dg-final { scan-assembler-times "vfmsub132sd" 20 } } */
-/* { dg-final { scan-assembler-times "vfmsub213sd" 20 } } */
-/* { dg-final { scan-assembler-times "vfnmadd132sd" 20 } } */
-/* { dg-final { scan-assembler-times "vfnmadd213sd" 20 } } */
-/* { dg-final { scan-assembler-times "vfnmsub132sd" 20 } } */
-/* { dg-final { scan-assembler-times "vfnmsub213sd" 20 } } */
+/* { dg-final { scan-assembler-times "vfmadd132sd" 16 } } */
+/* { dg-final { scan-assembler-times "vfmadd213sd" 16 } } */
+/* { dg-final { scan-assembler-times "vfmsub132sd" 16 } } */
+/* { dg-final { scan-assembler-times "vfmsub213sd" 16 } } */
+/* { dg-final { scan-assembler-times "vfnmadd132sd" 16 } } */
+/* { dg-final { scan-assembler-times "vfnmadd213sd" 16 } } */
+/* { dg-final { scan-assembler-times "vfnmsub132sd" 16 } } */
+/* { dg-final { scan-assembler-times "vfnmsub213sd" 16 } } */
diff --git a/gcc/testsuite/gcc.target/i386/l_fma_double_2.c b/gcc/testsuite/gcc.target/i386/l_fma_double_2.c
index 01173afb223..e8933e25d53 100644
--- a/gcc/testsuite/gcc.target/i386/l_fma_double_2.c
+++ b/gcc/testsuite/gcc.target/i386/l_fma_double_2.c
@@ -12,7 +12,7 @@
/* { dg-final { scan-assembler-times "vfmsub132pd" 8 } } */
/* { dg-final { scan-assembler-times "vfnmadd132pd" 8 } } */
/* { dg-final { scan-assembler-times "vfnmsub132pd" 8 } } */
-/* { dg-final { scan-assembler-times "vfmadd132sd" 40 } } */
-/* { dg-final { scan-assembler-times "vfmsub132sd" 40 } } */
-/* { dg-final { scan-assembler-times "vfnmadd132sd" 40 } } */
-/* { dg-final { scan-assembler-times "vfnmsub132sd" 40 } } */
+/* { dg-final { scan-assembler-times "vfmadd132sd" 32 } } */
+/* { dg-final { scan-assembler-times "vfmsub132sd" 32 } } */
+/* { dg-final { scan-assembler-times "vfnmadd132sd" 32 } } */
+/* { dg-final { scan-assembler-times "vfnmsub132sd" 32 } } */
diff --git a/gcc/testsuite/gcc.target/i386/l_fma_double_3.c b/gcc/testsuite/gcc.target/i386/l_fma_double_3.c
index 8cda521a870..00c756775c8 100644
--- a/gcc/testsuite/gcc.target/i386/l_fma_double_3.c
+++ b/gcc/testsuite/gcc.target/i386/l_fma_double_3.c
@@ -16,11 +16,11 @@
/* { dg-final { scan-assembler-times "vfnmadd231pd" 4 } } */
/* { dg-final { scan-assembler-times "vfnmsub132pd" 4 } } */
/* { dg-final { scan-assembler-times "vfnmsub231pd" 4 } } */
-/* { dg-final { scan-assembler-times "vfmadd132sd" 20 } } */
-/* { dg-final { scan-assembler-times "vfmadd213sd" 20 } } */
-/* { dg-final { scan-assembler-times "vfmsub132sd" 20 } } */
-/* { dg-final { scan-assembler-times "vfmsub213sd" 20 } } */
-/* { dg-final { scan-assembler-times "vfnmadd132sd" 20 } } */
-/* { dg-final { scan-assembler-times "vfnmadd213sd" 20 } } */
-/* { dg-final { scan-assembler-times "vfnmsub132sd" 20 } } */
-/* { dg-final { scan-assembler-times "vfnmsub213sd" 20 } } */
+/* { dg-final { scan-assembler-times "vfmadd132sd" 16 } } */
+/* { dg-final { scan-assembler-times "vfmadd213sd" 16 } } */
+/* { dg-final { scan-assembler-times "vfmsub132sd" 16 } } */
+/* { dg-final { scan-assembler-times "vfmsub213sd" 16 } } */
+/* { dg-final { scan-assembler-times "vfnmadd132sd" 16 } } */
+/* { dg-final { scan-assembler-times "vfnmadd213sd" 16 } } */
+/* { dg-final { scan-assembler-times "vfnmsub132sd" 16 } } */
+/* { dg-final { scan-assembler-times "vfnmsub213sd" 16 } } */
diff --git a/gcc/testsuite/gcc.target/i386/l_fma_double_4.c b/gcc/testsuite/gcc.target/i386/l_fma_double_4.c
index 9f2331b51e8..09970bdb5c6 100644
--- a/gcc/testsuite/gcc.target/i386/l_fma_double_4.c
+++ b/gcc/testsuite/gcc.target/i386/l_fma_double_4.c
@@ -12,7 +12,7 @@
/* { dg-final { scan-assembler-times "vfmsub132pd" 8 } } */
/* { dg-final { scan-assembler-times "vfnmadd132pd" 8 } } */
/* { dg-final { scan-assembler-times "vfnmsub132pd" 8 } } */
-/* { dg-final { scan-assembler-times "vfmadd132sd" 40 } } */
-/* { dg-final { scan-assembler-times "vfmsub132sd" 40 } } */
-/* { dg-final { scan-assembler-times "vfnmadd132sd" 40 } } */
-/* { dg-final { scan-assembler-times "vfnmsub132sd" 40 } } */
+/* { dg-final { scan-assembler-times "vfmadd132sd" 32 } } */
+/* { dg-final { scan-assembler-times "vfmsub132sd" 32 } } */
+/* { dg-final { scan-assembler-times "vfnmadd132sd" 32 } } */
+/* { dg-final { scan-assembler-times "vfnmsub132sd" 32 } } */
diff --git a/gcc/testsuite/gcc.target/i386/l_fma_double_5.c b/gcc/testsuite/gcc.target/i386/l_fma_double_5.c
index 9e33975b1e4..2a1428e4d9c 100644
--- a/gcc/testsuite/gcc.target/i386/l_fma_double_5.c
+++ b/gcc/testsuite/gcc.target/i386/l_fma_double_5.c
@@ -12,7 +12,7 @@
/* { dg-final { scan-assembler-times "vfmsub132pd" 8 } } */
/* { dg-final { scan-assembler-times "vfnmadd132pd" 8 } } */
/* { dg-final { scan-assembler-times "vfnmsub132pd" 8 } } */
-/* { dg-final { scan-assembler-times "vfmadd132sd" 40 } } */
-/* { dg-final { scan-assembler-times "vfmsub132sd" 40 } } */
-/* { dg-final { scan-assembler-times "vfnmadd132sd" 40 } } */
-/* { dg-final { scan-assembler-times "vfnmsub132sd" 40 } } */
+/* { dg-final { scan-assembler-times "vfmadd132sd" 32 } } */
+/* { dg-final { scan-assembler-times "vfmsub132sd" 32 } } */
+/* { dg-final { scan-assembler-times "vfnmadd132sd" 32 } } */
+/* { dg-final { scan-assembler-times "vfnmsub132sd" 32 } } */
diff --git a/gcc/testsuite/gcc.target/i386/l_fma_double_6.c b/gcc/testsuite/gcc.target/i386/l_fma_double_6.c
index 28d264dd20d..092032aa0b5 100644
--- a/gcc/testsuite/gcc.target/i386/l_fma_double_6.c
+++ b/gcc/testsuite/gcc.target/i386/l_fma_double_6.c
@@ -12,7 +12,7 @@
/* { dg-final { scan-assembler-times "vfmsub132pd" 8 } } */
/* { dg-final { scan-assembler-times "vfnmadd132pd" 8 } } */
/* { dg-final { scan-assembler-times "vfnmsub132pd" 8 } } */
-/* { dg-final { scan-assembler-times "vfmadd132sd" 40 } } */
-/* { dg-final { scan-assembler-times "vfmsub132sd" 40 } } */
-/* { dg-final { scan-assembler-times "vfnmadd132sd" 40 } } */
-/* { dg-final { scan-assembler-times "vfnmsub132sd" 40 } } */
+/* { dg-final { scan-assembler-times "vfmadd132sd" 32 } } */
+/* { dg-final { scan-assembler-times "vfmsub132sd" 32 } } */
+/* { dg-final { scan-assembler-times "vfnmadd132sd" 32 } } */
+/* { dg-final { scan-assembler-times "vfnmsub132sd" 32 } } */
diff --git a/gcc/testsuite/gcc.target/i386/l_fma_float_1.c b/gcc/testsuite/gcc.target/i386/l_fma_float_1.c
index fea0b20619d..4bcd81de9da 100644
--- a/gcc/testsuite/gcc.target/i386/l_fma_float_1.c
+++ b/gcc/testsuite/gcc.target/i386/l_fma_float_1.c
@@ -16,11 +16,11 @@
/* { dg-final { scan-assembler-times "vfnmadd231ps" 4 } } */
/* { dg-final { scan-assembler-times "vfnmsub132ps" 4 } } */
/* { dg-final { scan-assembler-times "vfnmsub231ps" 4 } } */
-/* { dg-final { scan-assembler-times "vfmadd132ss" 36 } } */
-/* { dg-final { scan-assembler-times "vfmadd213ss" 36 } } */
-/* { dg-final { scan-assembler-times "vfmsub132ss" 36 } } */
-/* { dg-final { scan-assembler-times "vfmsub213ss" 36 } } */
-/* { dg-final { scan-assembler-times "vfnmadd132ss" 36 } } */
-/* { dg-final { scan-assembler-times "vfnmadd213ss" 36 } } */
-/* { dg-final { scan-assembler-times "vfnmsub132ss" 36 } } */
-/* { dg-final { scan-assembler-times "vfnmsub213ss" 36 } } */
+/* { dg-final { scan-assembler-times "vfmadd132ss" 32 } } */
+/* { dg-final { scan-assembler-times "vfmadd213ss" 32 } } */
+/* { dg-final { scan-assembler-times "vfmsub132ss" 32 } } */
+/* { dg-final { scan-assembler-times "vfmsub213ss" 32 } } */
+/* { dg-final { scan-assembler-times "vfnmadd132ss" 32 } } */
+/* { dg-final { scan-assembler-times "vfnmadd213ss" 32 } } */
+/* { dg-final { scan-assembler-times "vfnmsub132ss" 32 } } */
+/* { dg-final { scan-assembler-times "vfnmsub213ss" 32 } } */
diff --git a/gcc/testsuite/gcc.target/i386/l_fma_float_2.c b/gcc/testsuite/gcc.target/i386/l_fma_float_2.c
index dd5f543f58c..34b7fcb6dd5 100644
--- a/gcc/testsuite/gcc.target/i386/l_fma_float_2.c
+++ b/gcc/testsuite/gcc.target/i386/l_fma_float_2.c
@@ -12,7 +12,7 @@
/* { dg-final { scan-assembler-times "vfmsub132ps" 8 } } */
/* { dg-final { scan-assembler-times "vfnmadd132ps" 8 } } */
/* { dg-final { scan-assembler-times "vfnmsub132ps" 8 } } */
-/* { dg-final { scan-assembler-times "vfmadd132ss" 72 } } */
-/* { dg-final { scan-assembler-times "vfmsub132ss" 72 } } */
-/* { dg-final { scan-assembler-times "vfnmadd132ss" 72 } } */
-/* { dg-final { scan-assembler-times "vfnmsub132ss" 72 } } */
+/* { dg-final { scan-assembler-times "vfmadd132ss" 64 } } */
+/* { dg-final { scan-assembler-times "vfmsub132ss" 64 } } */
+/* { dg-final { scan-assembler-times "vfnmadd132ss" 64 } } */
+/* { dg-final { scan-assembler-times "vfnmsub132ss" 64 } } */
diff --git a/gcc/testsuite/gcc.target/i386/l_fma_float_3.c b/gcc/testsuite/gcc.target/i386/l_fma_float_3.c
index 38853353b01..6ff2c6eacd5 100644
--- a/gcc/testsuite/gcc.target/i386/l_fma_float_3.c
+++ b/gcc/testsuite/gcc.target/i386/l_fma_float_3.c
@@ -16,11 +16,11 @@
/* { dg-final { scan-assembler-times "vfnmadd231ps" 4 } } */
/* { dg-final { scan-assembler-times "vfnmsub132ps" 4 } } */
/* { dg-final { scan-assembler-times "vfnmsub231ps" 4 } } */
-/* { dg-final { scan-assembler-times "vfmadd132ss" 36 } } */
-/* { dg-final { scan-assembler-times "vfmadd213ss" 36 } } */
-/* { dg-final { scan-assembler-times "vfmsub132ss" 36 } } */
-/* { dg-final { scan-assembler-times "vfmsub213ss" 36 } } */
-/* { dg-final { scan-assembler-times "vfnmadd132ss" 36 } } */
-/* { dg-final { scan-assembler-times "vfnmadd213ss" 36 } } */
-/* { dg-final { scan-assembler-times "vfnmsub132ss" 36 } } */
-/* { dg-final { scan-assembler-times "vfnmsub213ss" 36 } } */
+/* { dg-final { scan-assembler-times "vfmadd132ss" 32 } } */
+/* { dg-final { scan-assembler-times "vfmadd213ss" 32 } } */
+/* { dg-final { scan-assembler-times "vfmsub132ss" 32 } } */
+/* { dg-final { scan-assembler-times "vfmsub213ss" 32 } } */
+/* { dg-final { scan-assembler-times "vfnmadd132ss" 32 } } */
+/* { dg-final { scan-assembler-times "vfnmadd213ss" 32 } } */
+/* { dg-final { scan-assembler-times "vfnmsub132ss" 32 } } */
+/* { dg-final { scan-assembler-times "vfnmsub213ss" 32 } } */
diff --git a/gcc/testsuite/gcc.target/i386/l_fma_float_4.c b/gcc/testsuite/gcc.target/i386/l_fma_float_4.c
index 5a7bb217836..39548bfa76b 100644
--- a/gcc/testsuite/gcc.target/i386/l_fma_float_4.c
+++ b/gcc/testsuite/gcc.target/i386/l_fma_float_4.c
@@ -12,7 +12,7 @@
/* { dg-final { scan-assembler-times "vfmsub132ps" 8 } } */
/* { dg-final { scan-assembler-times "vfnmadd132ps" 8 } } */
/* { dg-final { scan-assembler-times "vfnmsub132ps" 8 } } */
-/* { dg-final { scan-assembler-times "vfmadd132ss" 72 } } */
-/* { dg-final { scan-assembler-times "vfmsub132ss" 72 } } */
-/* { dg-final { scan-assembler-times "vfnmadd132ss" 72 } } */
-/* { dg-final { scan-assembler-times "vfnmsub132ss" 72 } } */
+/* { dg-final { scan-assembler-times "vfmadd132ss" 64 } } */
+/* { dg-final { scan-assembler-times "vfmsub132ss" 64 } } */
+/* { dg-final { scan-assembler-times "vfnmadd132ss" 64 } } */
+/* { dg-final { scan-assembler-times "vfnmsub132ss" 64 } } */
diff --git a/gcc/testsuite/gcc.target/i386/l_fma_float_5.c b/gcc/testsuite/gcc.target/i386/l_fma_float_5.c
index 0b0454ed336..83d79512592 100644
--- a/gcc/testsuite/gcc.target/i386/l_fma_float_5.c
+++ b/gcc/testsuite/gcc.target/i386/l_fma_float_5.c
@@ -12,7 +12,7 @@
/* { dg-final { scan-assembler-times "vfmsub132ps" 8 } } */
/* { dg-final { scan-assembler-times "vfnmadd132ps" 8 } } */
/* { dg-final { scan-assembler-times "vfnmsub132ps" 8 } } */
-/* { dg-final { scan-assembler-times "vfmadd132ss" 72 } } */
-/* { dg-final { scan-assembler-times "vfmsub132ss" 72 } } */
-/* { dg-final { scan-assembler-times "vfnmadd132ss" 72 } } */
-/* { dg-final { scan-assembler-times "vfnmsub132ss" 72 } } */
+/* { dg-final { scan-assembler-times "vfmadd132ss" 64 } } */
+/* { dg-final { scan-assembler-times "vfmsub132ss" 64 } } */
+/* { dg-final { scan-assembler-times "vfnmadd132ss" 64 } } */
+/* { dg-final { scan-assembler-times "vfnmsub132ss" 64 } } */
diff --git a/gcc/testsuite/gcc.target/i386/l_fma_float_6.c b/gcc/testsuite/gcc.target/i386/l_fma_float_6.c
index 03bf8e84835..1eefc817c36 100644
--- a/gcc/testsuite/gcc.target/i386/l_fma_float_6.c
+++ b/gcc/testsuite/gcc.target/i386/l_fma_float_6.c
@@ -12,7 +12,7 @@
/* { dg-final { scan-assembler-times "vfmsub132ps" 8 } } */
/* { dg-final { scan-assembler-times "vfnmadd132ps" 8 } } */
/* { dg-final { scan-assembler-times "vfnmsub132ps" 8 } } */
-/* { dg-final { scan-assembler-times "vfmadd132ss" 72 } } */
-/* { dg-final { scan-assembler-times "vfmsub132ss" 72 } } */
-/* { dg-final { scan-assembler-times "vfnmadd132ss" 72 } } */
-/* { dg-final { scan-assembler-times "vfnmsub132ss" 72 } } */
+/* { dg-final { scan-assembler-times "vfmadd132ss" 64 } } */
+/* { dg-final { scan-assembler-times "vfmsub132ss" 64 } } */
+/* { dg-final { scan-assembler-times "vfnmadd132ss" 64 } } */
+/* { dg-final { scan-assembler-times "vfnmsub132ss" 64 } } */
diff --git a/gcc/testsuite/gcc.target/sh/pr54089-8.c b/gcc/testsuite/gcc.target/sh/pr54089-8.c
new file mode 100644
index 00000000000..fa9e8f38380
--- /dev/null
+++ b/gcc/testsuite/gcc.target/sh/pr54089-8.c
@@ -0,0 +1,203 @@
+/* Check that the rotcl instruction is generated. */
+/* { dg-do compile { target "sh*-*-*" } } */
+/* { dg-options "-O1" } */
+/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */
+/* { dg-final { scan-assembler-times "rotcl" 28 } } */
+
+typedef char bool;
+
+long long
+test_00 (long long a)
+{
+ return a << 1;
+}
+
+unsigned int
+test_01 (unsigned int a, int b, int c)
+{
+ bool r = b == c;
+ return ((a << 1) | r);
+}
+
+unsigned int
+test_02 (unsigned int a, int b, int c)
+{
+ bool r = b == c;
+ return ((a << 2) | r);
+}
+
+unsigned int
+test_03 (unsigned int a, int b, int c)
+{
+ bool r = b == c;
+ return ((a << 3) | r);
+}
+
+unsigned int
+test_04 (unsigned int a, int b, int c)
+{
+ bool r = b == c;
+ return ((a << 4) | r);
+}
+
+unsigned int
+test_05 (unsigned int a, int b, int c)
+{
+ bool r = b == c;
+ return ((a << 5) | r);
+}
+
+unsigned int
+test_06 (unsigned int a, int b, int c)
+{
+ bool r = b == c;
+ return ((a << 6) | r);
+}
+
+unsigned int
+test_07 (unsigned int a, int b, int c)
+{
+ bool r = b == c;
+ return ((a << 7) | r);
+}
+
+unsigned int
+test_08 (unsigned int a, int b, int c)
+{
+ bool r = b == c;
+ return ((a << 8) | r);
+}
+
+unsigned int
+test_09 (unsigned int a, int b, int c)
+{
+ bool r = b == c;
+ return ((a << 31) | r);
+}
+
+unsigned int
+test_10 (unsigned int a, int b)
+{
+ /* 1x shlr, 1x rotcl */
+ return (a << 1) | (b & 1);
+}
+
+unsigned int
+test_11 (unsigned int a, int b)
+{
+ /* 1x shlr, 1x rotcl (+1x add as shll) */
+ return (a << 2) | (b & 1);
+}
+
+unsigned int
+test_12 (unsigned int a, int b)
+{
+ /* 1x shlr, 1x shll2, 1x rotcl */
+ return (a << 3) | (b & 1);
+}
+
+unsigned int
+test_13 (unsigned int a, int b)
+{
+ /* 1x shll, 1x rotcl */
+ bool r = b < 0;
+ return (a << 1) | r;
+}
+
+unsigned int
+test_14 (unsigned int a, int b, int c)
+{
+ bool r = b != c;
+ return ((a << 1) | r);
+}
+
+unsigned int
+test_15 (unsigned int a, int b, int c)
+{
+ bool r = b != c;
+ return ((a << 11) | r);
+}
+
+unsigned int
+test_16 (unsigned int a, int b, int c)
+{
+ bool r = b != c;
+ return ((a << 3) | r);
+}
+
+unsigned int
+test_17 (unsigned int a, int b, int c)
+{
+ bool r = b != c;
+ return ((a << 4) | r);
+}
+
+unsigned int
+test_18 (unsigned int a, int b, int c)
+{
+ bool r = b != c;
+ return ((a << 5) | r);
+}
+
+unsigned int
+test_19 (unsigned int a, int b, int c)
+{
+ bool r = b != c;
+ return ((a << 6) | r);
+}
+
+unsigned int
+test_20 (unsigned int a, int b, int c)
+{
+ bool r = b != c;
+ return ((a << 7) | r);
+}
+
+unsigned int
+test_21 (unsigned int a, int b, int c)
+{
+ bool r = b != c;
+ return ((a << 8) | r);
+}
+
+unsigned int
+test_22 (unsigned int a, int b, int c)
+{
+ bool r = b != c;
+ return ((a << 31) | r);
+}
+
+unsigned int
+test_23 (unsigned int a, int b, int c)
+{
+ /* 1x shll, 1x rotcl */
+ return (a >> 31) | (b << 13);
+}
+
+unsigned int
+test_24 (unsigned int a, unsigned int b)
+{
+ /* 1x shll, 1x rotcl */
+ return (a >> 31) | (b << 1);
+}
+
+unsigned int
+test_25 (unsigned int a, unsigned int b)
+{
+ /* 1x shll, 1x rotcl */
+ return (a >> 31) | (b << 3);
+}
+
+unsigned int
+test_26 (unsigned int a, unsigned int b)
+{
+ /* 1x shll, 1x rotcl */
+ return (b << 3) | (a >> 31);
+}
+
+unsigned int
+test_27 (unsigned int a, unsigned int b)
+{
+ /* 1x shlr, 1x rotcl */
+ return (a << 1) | ((b >> 4) & 1);
+}
diff --git a/gcc/testsuite/gcc.target/sh/pr54089-9.c b/gcc/testsuite/gcc.target/sh/pr54089-9.c
new file mode 100644
index 00000000000..bd889dc34be
--- /dev/null
+++ b/gcc/testsuite/gcc.target/sh/pr54089-9.c
@@ -0,0 +1,63 @@
+/* Check that the rotcr instruction is generated. */
+/* { dg-do compile { target "sh*-*-*" } } */
+/* { dg-options "-O1" } */
+/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */
+/* { dg-final { scan-assembler-times "rotcl" 4 } } */
+/* { dg-final { scan-assembler-not "movt" } } */
+/* { dg-final { scan-assembler-not "or\t" } } */
+/* { dg-final { scan-assembler-not "rotl" } } */
+/* { dg-final { scan-assembler-not "and" } } */
+
+typedef char bool;
+
+int
+test_00 (int* a, int* b)
+{
+ int i;
+ int r = 0;
+ for (i = 0; i < 16; ++i)
+ {
+ bool t = a[i] == b[i];
+ r = (r << 1) | t;
+ }
+ return r;
+}
+
+int
+test_01 (int* a, int* b)
+{
+ int i;
+ int r = 0;
+ for (i = 0; i < 16; ++i)
+ {
+ bool t = a[i] == b[i];
+ r = (r << 2) | t;
+ }
+ return r;
+}
+
+int
+test_02 (int* a, int* b)
+{
+ int i;
+ int r = 0;
+ for (i = 0; i < 16; ++i)
+ {
+ bool t = a[i] == b[i];
+ r = (r << 3) | t;
+ }
+ return r;
+}
+
+int
+test_03 (const bool* a)
+{
+ int i;
+ int r = 0;
+ for (i = 0; i < 16; ++i)
+ {
+ bool t = a[i];
+ r = (r << 1) | (t & 1);
+ }
+ return r;
+}
diff --git a/gcc/testsuite/gfortran.dg/transfer_class_1.f90 b/gcc/testsuite/gfortran.dg/transfer_class_1.f90
new file mode 100644
index 00000000000..00b3a2405f3
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/transfer_class_1.f90
@@ -0,0 +1,16 @@
+! { dg-do compile }
+! { dg-options "-Wsurprising" }
+!
+! PR 54917: [4.7/4.8 Regression] [OOP] TRANSFER on polymorphic variable causes ICE
+!
+! Contributed by Sean Santos <quantheory@gmail.com>
+
+subroutine test_routine1(arg)
+ implicit none
+ type test_type
+ integer :: test_comp
+ end type
+ class(test_type) :: arg
+ integer :: i
+ i = transfer(arg, 1)
+end subroutine
diff --git a/gcc/testsuite/gfortran.dg/transfer_class_2.f90 b/gcc/testsuite/gfortran.dg/transfer_class_2.f90
new file mode 100644
index 00000000000..d75b640f10f
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/transfer_class_2.f90
@@ -0,0 +1,45 @@
+! { dg-do run }
+!
+! PR 54917: [OOP] TRANSFER on polymorphic variable causes ICE
+!
+! Contributed by Janus Weil <janus@gcc.gnu.org>
+
+module m
+ implicit none
+ type test_type
+ integer :: i = 0
+ contains
+ procedure :: ass
+ generic :: assignment(=) => ass
+ end type
+contains
+ subroutine ass (a, b)
+ class(test_type), intent(out) :: a
+ class(test_type), intent(in) :: b
+ a%i = b%i
+ end subroutine
+end module
+
+
+program p
+ use m
+ implicit none
+
+ class(test_type), allocatable :: c
+ type(test_type) :: t
+
+ allocate(c)
+
+ ! (1) check CLASS-to-TYPE transfer
+ c%i=3
+ t = transfer(c, t)
+ if (t%i /= 3) call abort()
+
+ ! (2) check TYPE-to-CLASS transfer
+ t%i=4
+ c = transfer(t, c)
+ if (c%i /= 4) call abort()
+
+end
+
+! { dg-final { cleanup-modules "m" } }
diff --git a/gcc/tree-ssa-loop-ivcanon.c b/gcc/tree-ssa-loop-ivcanon.c
index 58f45d2d1c4..601223b3dda 100644
--- a/gcc/tree-ssa-loop-ivcanon.c
+++ b/gcc/tree-ssa-loop-ivcanon.c
@@ -140,6 +140,20 @@ struct loop_size
instructions after exit are not executed. */
int last_iteration;
int last_iteration_eliminated_by_peeling;
+
+ /* If some IV computation will become constant. */
+ bool constant_iv;
+
+ /* Number of call stmts that are not a builtin and are pure or const
+ present on the hot path. */
+ int num_pure_calls_on_hot_path;
+ /* Number of call stmts that are not a builtin and are not pure nor const
+ present on the hot path. */
+ int num_non_pure_calls_on_hot_path;
+ /* Number of statements other than calls in the loop. */
+ int non_call_stmts_on_hot_path;
+ /* Number of branches seen on the hot path. */
+ int num_branches_on_hot_path;
};
/* Return true if OP in STMT will be constant after peeling LOOP. */
@@ -188,7 +202,11 @@ constant_after_peeling (tree op, gimple stmt, struct loop *loop)
return true;
}
-/* Computes an estimated number of insns in LOOP, weighted by WEIGHTS.
+/* Computes an estimated number of insns in LOOP.
+ EXIT (if non-NULL) is an exite edge that will be eliminated in all but last
+ iteration of the loop.
+ EDGE_TO_CANCEL (if non-NULL) is an non-exit edge eliminated in the last iteration
+ of loop.
Return results in SIZE, estimate benefits for complete unrolling exiting by EXIT. */
static void
@@ -198,11 +216,17 @@ tree_estimate_loop_size (struct loop *loop, edge exit, edge edge_to_cancel, stru
gimple_stmt_iterator gsi;
unsigned int i;
bool after_exit;
+ VEC (basic_block, heap) *path = get_loop_hot_path (loop);
size->overall = 0;
size->eliminated_by_peeling = 0;
size->last_iteration = 0;
size->last_iteration_eliminated_by_peeling = 0;
+ size->num_pure_calls_on_hot_path = 0;
+ size->num_non_pure_calls_on_hot_path = 0;
+ size->non_call_stmts_on_hot_path = 0;
+ size->num_branches_on_hot_path = 0;
+ size->constant_iv = 0;
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "Estimating sizes for loop %i\n", loop->num);
@@ -221,6 +245,8 @@ tree_estimate_loop_size (struct loop *loop, edge exit, edge edge_to_cancel, stru
gimple stmt = gsi_stmt (gsi);
int num = estimate_num_insns (stmt, &eni_size_weights);
bool likely_eliminated = false;
+ bool likely_eliminated_last = false;
+ bool likely_eliminated_peeled = false;
if (dump_file && (dump_flags & TDF_DETAILS))
{
@@ -231,11 +257,21 @@ tree_estimate_loop_size (struct loop *loop, edge exit, edge edge_to_cancel, stru
/* Look for reasons why we might optimize this stmt away. */
/* Exit conditional. */
- if (exit && body[i] == exit->src && stmt == last_stmt (exit->src))
+ if (exit && body[i] == exit->src
+ && stmt == last_stmt (exit->src))
{
if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, " Exit condition will be eliminated.\n");
- likely_eliminated = true;
+ fprintf (dump_file, " Exit condition will be eliminated "
+ "in peeled copies.\n");
+ likely_eliminated_peeled = true;
+ }
+ else if (edge_to_cancel && body[i] == edge_to_cancel->src
+ && stmt == last_stmt (edge_to_cancel->src))
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, " Exit condition will be eliminated "
+ "in last copy.\n");
+ likely_eliminated_last = true;
}
/* Sets of IV variables */
else if (gimple_code (stmt) == GIMPLE_ASSIGN
@@ -249,19 +285,22 @@ tree_estimate_loop_size (struct loop *loop, edge exit, edge edge_to_cancel, stru
/* Assignments of IV variables. */
else if (gimple_code (stmt) == GIMPLE_ASSIGN
&& TREE_CODE (gimple_assign_lhs (stmt)) == SSA_NAME
- && constant_after_peeling (gimple_assign_rhs1 (stmt), stmt,loop)
+ && constant_after_peeling (gimple_assign_rhs1 (stmt), stmt, loop)
&& (gimple_assign_rhs_class (stmt) != GIMPLE_BINARY_RHS
|| constant_after_peeling (gimple_assign_rhs2 (stmt),
stmt, loop)))
{
+ size->constant_iv = true;
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, " Constant expression will be folded away.\n");
likely_eliminated = true;
}
/* Conditionals. */
- else if (gimple_code (stmt) == GIMPLE_COND
- && constant_after_peeling (gimple_cond_lhs (stmt), stmt, loop)
- && constant_after_peeling (gimple_cond_rhs (stmt), stmt, loop))
+ else if ((gimple_code (stmt) == GIMPLE_COND
+ && constant_after_peeling (gimple_cond_lhs (stmt), stmt, loop)
+ && constant_after_peeling (gimple_cond_rhs (stmt), stmt, loop))
+ || (gimple_code (stmt) == GIMPLE_SWITCH
+ && constant_after_peeling (gimple_switch_index (stmt), stmt, loop)))
{
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, " Constant conditional.\n");
@@ -269,16 +308,49 @@ tree_estimate_loop_size (struct loop *loop, edge exit, edge edge_to_cancel, stru
}
size->overall += num;
- if (likely_eliminated)
+ if (likely_eliminated || likely_eliminated_peeled)
size->eliminated_by_peeling += num;
if (!after_exit)
{
size->last_iteration += num;
- if (likely_eliminated)
+ if (likely_eliminated || likely_eliminated_last)
size->last_iteration_eliminated_by_peeling += num;
}
}
}
+ while (VEC_length (basic_block, path))
+ {
+ basic_block bb = VEC_pop (basic_block, path);
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ gimple stmt = gsi_stmt (gsi);
+ if (gimple_code (stmt) == GIMPLE_CALL)
+ {
+ int flags = gimple_call_flags (stmt);
+ tree decl = gimple_call_fndecl (stmt);
+
+ if (decl && DECL_IS_BUILTIN (decl)
+ && is_inexpensive_builtin (decl))
+ ;
+ else if (flags & (ECF_PURE | ECF_CONST))
+ size->num_pure_calls_on_hot_path++;
+ else
+ size->num_non_pure_calls_on_hot_path++;
+ size->num_branches_on_hot_path ++;
+ }
+ else if (gimple_code (stmt) != GIMPLE_CALL
+ && gimple_code (stmt) != GIMPLE_DEBUG)
+ size->non_call_stmts_on_hot_path++;
+ if (((gimple_code (stmt) == GIMPLE_COND
+ && (!constant_after_peeling (gimple_cond_lhs (stmt), stmt, loop)
+ || constant_after_peeling (gimple_cond_rhs (stmt), stmt, loop)))
+ || (gimple_code (stmt) == GIMPLE_SWITCH
+ && !constant_after_peeling (gimple_switch_index (stmt), stmt, loop)))
+ && (!exit || bb != exit->src))
+ size->num_branches_on_hot_path++;
+ }
+ }
+ VEC_free (basic_block, heap, path);
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "size: %i-%i, last_iteration: %i-%i\n", size->overall,
size->eliminated_by_peeling, size->last_iteration,
@@ -644,34 +716,85 @@ try_unroll_loop_completely (struct loop *loop,
(int) unr_insns);
}
+ /* If the code is going to shrink, we don't need to be extra cautious
+ on guessing if the unrolling is going to be profitable. */
+ if (unr_insns
+ /* If there is IV variable that will become constant, we save
+ one instruction in the loop prologue we do not account
+ otherwise. */
+ <= ninsns + (size.constant_iv != false))
+ ;
/* We unroll only inner loops, because we do not consider it profitable
otheriwse. We still can cancel loopback edge of not rolling loop;
this is always a good idea. */
- if (loop->inner && unr_insns > ninsns)
+ else if (ul == UL_NO_GROWTH)
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "Not unrolling loop %d: size would grow.\n",
+ loop->num);
+ return false;
+ }
+ /* Outer loops tend to be less interesting candidates for complette
+ unrolling unless we can do a lot of propagation into the inner loop
+ body. For now we disable outer loop unrolling when the code would
+ grow. */
+ else if (loop->inner)
{
if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "Not unrolling loop %d:"
+ fprintf (dump_file, "Not unrolling loop %d: "
"it is not innermost and code would grow.\n",
loop->num);
return false;
}
-
- if (unr_insns > ninsns
- && (unr_insns
- > (unsigned) PARAM_VALUE (PARAM_MAX_COMPLETELY_PEELED_INSNS)))
+ /* If there is call on a hot path through the loop, then
+ there is most probably not much to optimize. */
+ else if (size.num_non_pure_calls_on_hot_path)
{
if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "Not unrolling loop %d "
- "(--param max-completely-peeled-insns limit reached).\n",
+ fprintf (dump_file, "Not unrolling loop %d: "
+ "contains call and code would grow.\n",
loop->num);
return false;
}
-
- if (ul == UL_NO_GROWTH
- && unr_insns > ninsns)
+ /* If there is pure/const call in the function, then we
+ can still optimize the unrolled loop body if it contains
+ some other interesting code than the calls and code
+ storing or cumulating the return value. */
+ else if (size.num_pure_calls_on_hot_path
+ /* One IV increment, one test, one ivtmp store
+ and one usefull stmt. That is about minimal loop
+ doing pure call. */
+ && (size.non_call_stmts_on_hot_path
+ <= 3 + size.num_pure_calls_on_hot_path))
{
if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "Not unrolling loop %d: size would grow.\n",
+ fprintf (dump_file, "Not unrolling loop %d: "
+ "contains just pure calls and code would grow.\n",
+ loop->num);
+ return false;
+ }
+ /* Complette unrolling is major win when control flow is removed and
+ one big basic block is created. If the loop contains control flow
+ the optimization may still be a win because of eliminating the loop
+ overhead but it also may blow the branch predictor tables.
+ Limit number of branches on the hot path through the peeled
+ sequence. */
+ else if (size.num_branches_on_hot_path * (int)n_unroll
+ > PARAM_VALUE (PARAM_MAX_PEEL_BRANCHES))
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "Not unrolling loop %d: "
+ " number of branches on hot path in the unrolled sequence"
+ " reach --param max-peel-branches limit.\n",
+ loop->num);
+ return false;
+ }
+ else if (unr_insns
+ > (unsigned) PARAM_VALUE (PARAM_MAX_COMPLETELY_PEELED_INSNS))
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "Not unrolling loop %d: "
+ "(--param max-completely-peeled-insns limit reached).\n",
loop->num);
return false;
}
@@ -689,6 +812,8 @@ try_unroll_loop_completely (struct loop *loop,
{
free_original_copy_tables ();
free (wont_exit);
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "Failed to duplicate the loop\n");
return false;
}
@@ -968,7 +1093,7 @@ tree_unroll_loops_completely (bool may_increase_size, bool unroll_outer)
{
struct loop *loop_father = loop_outer (loop);
- if (may_increase_size && optimize_loop_for_speed_p (loop)
+ if (may_increase_size && optimize_loop_nest_for_speed_p (loop)
/* Unroll outermost loops only if asked to do so or they do
not cause code growth. */
&& (unroll_outer || loop_outer (loop_father)))
diff --git a/gcc/tree-vect-loop-manip.c b/gcc/tree-vect-loop-manip.c
index 3c356e35b6f..58ded23399e 100644
--- a/gcc/tree-vect-loop-manip.c
+++ b/gcc/tree-vect-loop-manip.c
@@ -1954,9 +1954,16 @@ vect_do_peeling_for_loop_bound (loop_vec_info loop_vinfo, tree *ratio,
by ratio_mult_vf_name steps. */
vect_update_ivs_after_vectorizer (loop_vinfo, ratio_mult_vf_name, update_e);
- max_iter = LOOP_VINFO_VECT_FACTOR (loop_vinfo) - 1;
+ /* For vectorization factor N, we need to copy last N-1 values in epilogue
+ and this means N-2 loopback edge executions.
+
+ PEELING_FOR_GAPS works by subtracting last iteration and thus the epilogue
+ will execute at least LOOP_VINFO_VECT_FACTOR times. */
+ max_iter = (LOOP_VINFO_PEELING_FOR_GAPS (loop_vinfo)
+ ? LOOP_VINFO_VECT_FACTOR (loop_vinfo) * 2
+ : LOOP_VINFO_VECT_FACTOR (loop_vinfo)) - 2;
if (check_profitability)
- max_iter = MAX (max_iter, (int) th);
+ max_iter = MAX (max_iter, (int) th - 1);
record_niter_bound (new_loop, double_int::from_shwi (max_iter), false, true);
dump_printf (MSG_OPTIMIZED_LOCATIONS,
"Setting upper bound of nb iterations for epilogue "
@@ -2186,9 +2193,11 @@ vect_do_peeling_for_alignment (loop_vec_info loop_vinfo,
#ifdef ENABLE_CHECKING
slpeel_verify_cfg_after_peeling (new_loop, loop);
#endif
- max_iter = LOOP_VINFO_VECT_FACTOR (loop_vinfo) - 1;
+ /* For vectorization factor N, we need to copy at most N-1 values
+ for alignment and this means N-2 loopback edge executions. */
+ max_iter = LOOP_VINFO_VECT_FACTOR (loop_vinfo) - 2;
if (check_profitability)
- max_iter = MAX (max_iter, (int) th);
+ max_iter = MAX (max_iter, (int) th - 1);
record_niter_bound (new_loop, double_int::from_shwi (max_iter), false, true);
dump_printf (MSG_OPTIMIZED_LOCATIONS,
"Setting upper bound of nb iterations for prologue "
diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
index 908caed0b57..5e99857efd6 100644
--- a/gcc/tree-vect-loop.c
+++ b/gcc/tree-vect-loop.c
@@ -5448,10 +5448,16 @@ vect_transform_loop (loop_vec_info loop_vinfo)
bool transform_pattern_stmt = false;
bool check_profitability = false;
int th;
+ /* Record number of iterations before we started tampering with the profile. */
+ gcov_type expected_iterations = expected_loop_iterations_unbounded (loop);
if (dump_enabled_p ())
dump_printf_loc (MSG_NOTE, vect_location, "=== vec_transform_loop ===");
+ /* If profile is inprecise, we have chance to fix it up. */
+ if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo))
+ expected_iterations = LOOP_VINFO_INT_NITERS (loop_vinfo);
+
/* Use the more conservative vectorization threshold. If the number
of iterations is constant assume the cost check has been performed
by our caller. If the threshold makes all loops profitable that
@@ -5735,6 +5741,25 @@ vect_transform_loop (loop_vec_info loop_vinfo)
slpeel_make_loop_iterate_ntimes (loop, ratio);
+ /* Reduce loop iterations by the vectorization factor. */
+ scale_loop_profile (loop, RDIV (REG_BR_PROB_BASE , vectorization_factor),
+ expected_iterations / vectorization_factor);
+ loop->nb_iterations_upper_bound
+ = loop->nb_iterations_upper_bound.udiv (double_int::from_uhwi (vectorization_factor),
+ FLOOR_DIV_EXPR);
+ if (LOOP_VINFO_PEELING_FOR_GAPS (loop_vinfo)
+ && loop->nb_iterations_upper_bound != double_int_zero)
+ loop->nb_iterations_upper_bound = loop->nb_iterations_upper_bound - double_int_one;
+ if (loop->any_estimate)
+ {
+ loop->nb_iterations_estimate
+ = loop->nb_iterations_estimate.udiv (double_int::from_uhwi (vectorization_factor),
+ FLOOR_DIV_EXPR);
+ if (LOOP_VINFO_PEELING_FOR_GAPS (loop_vinfo)
+ && loop->nb_iterations_estimate != double_int_zero)
+ loop->nb_iterations_estimate = loop->nb_iterations_estimate - double_int_one;
+ }
+
/* The memory tags and pointers in vectorized statements need to
have their SSA forms updated. FIXME, why can't this be delayed
until all the loops have been transformed? */
diff --git a/gcc/tree.h b/gcc/tree.h
index d921886c2ea..5fe1f1f46bd 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -3480,6 +3480,12 @@ extern VEC(tree, gc) **decl_debug_args_insert (tree);
#define DECL_FUNCTION_SPECIFIC_OPTIMIZATION(NODE) \
(FUNCTION_DECL_CHECK (NODE)->function_decl.function_specific_optimization)
+/* In FUNCTION_DECL, this is set if this function has other versions generated
+ using "target" attributes. The default version is the one which does not
+ have any "target" attribute set. */
+#define DECL_FUNCTION_VERSIONED(NODE)\
+ (FUNCTION_DECL_CHECK (NODE)->function_decl.versioned_function)
+
/* FUNCTION_DECL inherits from DECL_NON_COMMON because of the use of the
arguments/result/saved_tree fields by front ends. It was either inherit
FUNCTION_DECL from non_common, or inherit non_common from FUNCTION_DECL,
@@ -3524,8 +3530,8 @@ struct GTY(()) tree_function_decl {
unsigned looping_const_or_pure_flag : 1;
unsigned has_debug_args_flag : 1;
unsigned tm_clone_flag : 1;
-
- /* 1 bit left */
+ unsigned versioned_function : 1;
+ /* No bits left. */
};
/* The source language of the translation-unit. */
diff --git a/libada/ChangeLog b/libada/ChangeLog
index 1778a14e4a2..6172aad82cc 100644
--- a/libada/ChangeLog
+++ b/libada/ChangeLog
@@ -1,3 +1,16 @@
+2012-10-30 Arnaud Charlet <charlet@adacore.com>
+
+ * Makefile.in (osconstool): Revert previous change, still needed
+ after all. Add call to copy-s-oscons target.
+
+2012-10-30 Arnaud Charlet <charlet@adacore.com>
+
+ * Makefile.in (osconstool): Removed, no longer needed.
+
+2012-10-30 Arnaud Charlet <charlet@adacore.com>
+
+ * Makefile.in (osconstool): Fix target.
+
2012-06-11 Olivier Hainque <hainque@adacore.com>
* Makefile.in (GNATLIBCFLAGS_FOR_C): Remove $(PICFLAG).
diff --git a/libada/Makefile.in b/libada/Makefile.in
index 389a2fb2f79..863b136fc85 100644
--- a/libada/Makefile.in
+++ b/libada/Makefile.in
@@ -113,7 +113,8 @@ gnatlib-sjlj gnatlib-zcx gnatlib-shared: osconstool $(GCC_DIR)/ada/Makefile
$(LN_S) $(ADA_RTS_DIR) adalib
osconstool:
- $(MAKE) -C $(GCC_DIR)/ada $(LIBADA_FLAGS_TO_PASS) ./bldtools/oscons/xoscons
+ $(MAKE) -C $(GCC_DIR) $(LIBADA_FLAGS_TO_PASS) ada/s-oscons.ads
+ $(MAKE) -C $(GCC_DIR)/ada $(LIBADA_FLAGS_TO_PASS) copy-s-oscons
install-gnatlib: $(GCC_DIR)/ada/Makefile
$(MAKE) -C $(GCC_DIR)/ada $(LIBADA_FLAGS_TO_PASS) install-gnatlib
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 2f02107bb63..5a252ed33ff 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,78 @@
+2012-11-06 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * include/bits/atomic_base.h: Don't include <cstddef>, use nullptr.
+ * include/std/atomic: Likewise.
+ * include/tr2/dynamic_bitset: Likewise.
+
+ * libsupc++/vec.cc (compute_size(std::size_t, std::size_t,
+ std::size_t)): Fix for -fno-exceptions.
+
+2012-11-06 Jonathan Wakely <jwakely.gcc@gmail.com>
+
+ * include/profile/map.h (map::emplace_hint): Add missing return.
+
+2012-11-05 Jonathan Wakely <jwakely.gcc@gmail.com>
+
+ * include/profile/deque: Constrain InputIterator parameters.
+ * include/profile/forward_list: Likewise.
+ * include/profile/list: Likewise.
+ * include/profile/map.h: Likewise.
+ * include/profile/multimap.h: Likewise.
+ * include/profile/set.h: Likewise.
+ * include/profile/multiset.h: Likewise.
+ * include/profile/vector: Likewise.
+
+2012-11-05 Jonathan Wakely <jwakely.gcc@gmail.com>
+
+ * include/profile/forward_list: Update to meet allocator-aware
+ requirements.
+ * include/debug/forward_list: Likewise.
+ * include/debug/vector: Verify allocators are swapped or equal.
+ * include/debug/macros.h (__glibcxx_check_equal_allocs): Define.
+ * include/debug/formatter.h: Add new debug message.
+ * src/c++11/debug.cc: Likewise.
+ * testsuite/23_containers/forward_list/allocator/swap.cc: Do not
+ swap containers with non-propagating, non-equal allocators.
+ * testsuite/23_containers/vector/allocator/swap.cc: Likewise.
+
+2012-11-05 Benjamin Kosnik <bkoz@redhat.com>
+ Oleg Smolsky <oleg@smolsky.net>
+
+ PR libstdc++/55028
+ * config/abi/pre/gnu-versioned-namespace.ver: Add symbols.
+ * testsuite/23_containers/unordered_multimap/insert/55028-debug.cc: New.
+
+2012-10-05 François Dumont <fdumont@gcc.gnu.org>
+
+ * include/ext/throw_allocator.h (__throw_value_base): Add move
+ semantic, not throwing.
+ (__throw_value_limit): Likewise.
+ (__throw_value_random): Likewise.
+ * testsuite/util/exception/safety.h: Add validation of C++11
+ methods emplace/emplace_front/emplace_back/emplace_hint.
+ * testsuite/util/testsuite_container_traits.h: Signal emplace
+ support on deque, forward_list, list and vector.
+ * testsuite/23_containers/deque/requirements/exception/
+ propagation_consistent.cc: Remove dg-do run fail.
+
+2012-11-05 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR libstdc++/55215
+ * include/bits/random.tcc (mersenne_twister_engine<>::seed(_Sseq&)):
+ Assign state_size to _M_p.
+ * testsuite/26_numerics/random/mersenne_twister_engine/cons/55215.cc:
+ New.
+ * testsuite/26_numerics/random/independent_bits_engine/cons/55215.cc:
+ Likewise.
+ * testsuite/26_numerics/random/shuffle_order_engine/cons/55215.cc:
+ Likewise.
+ * testsuite/26_numerics/random/subtract_with_carry_engine/cons/
+ 55215.cc: Likewise.
+ * testsuite/26_numerics/random/discard_block_engine/cons/55215.cc:
+ Likewise.
+ * testsuite/26_numerics/random/linear_congruential_engine/cons/
+ 55215.cc: Likewise.
+
2012-11-03 Florian Weimer <fweimer@redhat.com>
* libsupc++/vec.cc (compute_size): New.
@@ -23,14 +98,12 @@
* doc/xml/manual/prerequisites.xml: Remove detailed reference
to binutils downloads.
-
-
2012-11-02 Paolo Carlini <paolo.carlini@oracle.com>
PR libstdc++/55169
* include/bits/random.h: Remove all uses of param().
(chi_squared_distribution<>::__generate_impl(_ForwardIterator,
- _ForwardIterator, _UniformRandomNumberGenerator&): Declare
+ _ForwardIterator, _UniformRandomNumberGenerator&)): Declare
* include/bits/random.tcc: ... define.
* include/ext/random: Remove all uses of param().
diff --git a/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver b/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver
index 84210e4ec0a..d13c05926fa 100644
--- a/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver
+++ b/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver
@@ -64,6 +64,7 @@ GLIBCXX_7.0 {
# vtable
_ZTVSt*;
_ZTVNSt*;
+ _ZTVN9__gnu_cxx3__718stdio_sync_filebufI[cw]NSt3__711char_traitsI[cw]EEEE;
# thunk
_ZTv0_n24_NS*;
@@ -145,6 +146,14 @@ GLIBCXX_7.0 {
_ZNK11__gnu_debug16_Error_formatter8_M_error*;
_ZNK11__gnu_debug16_Error_formatter17_M_get_max_lengthEv;
+ # __gnu_debug::_Safe_unordered_container_base
+ # __gnu_debug::_Safe_local_iterator_base
+ _ZN11__gnu_debug30_Safe_unordered_container_base7_M_swapERS0_;
+ _ZN11__gnu_debug30_Safe_unordered_container_base13_M_detach_allEv;
+ _ZN11__gnu_debug25_Safe_local_iterator_base9_M_attachEPNS_19_Safe_sequence_baseEb;
+ _ZN11__gnu_debug25_Safe_local_iterator_base9_M_detachEv;
+
+
# parallel mode
_ZN14__gnu_parallel9_Settings3getEv;
_ZN14__gnu_parallel9_Settings3setERS0_;
diff --git a/libstdc++-v3/include/bits/atomic_base.h b/libstdc++-v3/include/bits/atomic_base.h
index af8a92436b2..8ce55530dd9 100644
--- a/libstdc++-v3/include/bits/atomic_base.h
+++ b/libstdc++-v3/include/bits/atomic_base.h
@@ -1,6 +1,6 @@
// -*- C++ -*- header.
-// Copyright (C) 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
+// Copyright (C) 2008-2012 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@@ -35,7 +35,6 @@
#include <bits/c++config.h>
#include <stdbool.h>
#include <stdint.h>
-#include <cstddef>
#include <bits/atomic_lockfree_defines.h>
namespace std _GLIBCXX_VISIBILITY(default)
@@ -423,11 +422,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
bool
is_lock_free() const noexcept
- { return __atomic_is_lock_free(sizeof(_M_i), NULL); }
+ { return __atomic_is_lock_free(sizeof(_M_i), nullptr); }
bool
is_lock_free() const volatile noexcept
- { return __atomic_is_lock_free(sizeof(_M_i), NULL); }
+ { return __atomic_is_lock_free(sizeof(_M_i), nullptr); }
void
store(__int_type __i, memory_order __m = memory_order_seq_cst) noexcept
@@ -717,11 +716,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
bool
is_lock_free() const noexcept
- { return __atomic_is_lock_free(_M_type_size(1), NULL); }
+ { return __atomic_is_lock_free(_M_type_size(1), nullptr); }
bool
is_lock_free() const volatile noexcept
- { return __atomic_is_lock_free(_M_type_size(1), NULL); }
+ { return __atomic_is_lock_free(_M_type_size(1), nullptr); }
void
store(__pointer_type __p,
diff --git a/libstdc++-v3/include/bits/random.tcc b/libstdc++-v3/include/bits/random.tcc
index 0f44ee85229..54a0c22fce1 100644
--- a/libstdc++-v3/include/bits/random.tcc
+++ b/libstdc++-v3/include/bits/random.tcc
@@ -385,6 +385,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
if (__zero)
_M_x[0] = __detail::_Shift<_UIntType, __w - 1>::__value;
+ _M_p = state_size;
}
template<typename _UIntType, size_t __w,
diff --git a/libstdc++-v3/include/debug/formatter.h b/libstdc++-v3/include/debug/formatter.h
index 1d29d8ce55a..d622ed1cdba 100644
--- a/libstdc++-v3/include/debug/formatter.h
+++ b/libstdc++-v3/include/debug/formatter.h
@@ -114,7 +114,8 @@ namespace __gnu_debug
__msg_self_move_assign,
// unordered container buckets
__msg_bucket_index_oob,
- __msg_valid_load_factor
+ __msg_valid_load_factor,
+ __msg_equal_allocs
};
class _Error_formatter
diff --git a/libstdc++-v3/include/debug/forward_list b/libstdc++-v3/include/debug/forward_list
index 8ad4336663e..61ae6ed6297 100644
--- a/libstdc++-v3/include/debug/forward_list
+++ b/libstdc++-v3/include/debug/forward_list
@@ -49,6 +49,12 @@ namespace __debug
typedef typename _Base::iterator _Base_iterator;
typedef typename _Base::const_iterator _Base_const_iterator;
+
+ typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
+ rebind<_GLIBCXX_STD_C::_Fwd_list_node<_Tp>>::other _Node_alloc_type;
+
+ typedef __gnu_cxx::__alloc_traits<_Node_alloc_type> _Node_alloc_traits;
+
public:
typedef typename _Base::reference reference;
typedef typename _Base::const_reference const_reference;
@@ -78,12 +84,15 @@ namespace __debug
forward_list(forward_list&& __list, const _Alloc& __al)
: _Base(std::move(__list._M_base()), __al)
{
- this->_M_swap(__list);
+ if (__list.get_allocator() == __al)
+ this->_M_swap(__list);
+ else
+ __list._M_invalidate_all();
}
explicit
- forward_list(size_type __n)
- : _Base(__n)
+ forward_list(size_type __n, const _Alloc& __al = _Alloc())
+ : _Base(__n, __al)
{ }
forward_list(size_type __n, const _Tp& __value,
@@ -128,12 +137,17 @@ namespace __debug
forward_list&
operator=(forward_list&& __list)
+ noexcept(_Node_alloc_traits::_S_nothrow_move())
{
- // NB: DR 1204.
- // NB: DR 675.
__glibcxx_check_self_move_assign(__list);
- clear();
- swap(__list);
+ bool xfer_memory = _Node_alloc_traits::_S_propagate_on_move_assign()
+ || __list.get_allocator() == this->get_allocator();
+ static_cast<_Base&>(*this) = std::move(__list);
+ if (xfer_memory)
+ this->_M_swap(__list);
+ else
+ this->_M_invalidate_all();
+ __list._M_invalidate_all();
return *this;
}
@@ -333,7 +347,10 @@ namespace __debug
void
swap(forward_list& __list)
+ noexcept(_Node_alloc_traits::_S_nothrow_swap())
{
+ if (!_Node_alloc_traits::_S_propagate_on_swap())
+ __glibcxx_check_equal_allocs(__list);
_Base::swap(__list);
this->_M_swap(__list);
}
diff --git a/libstdc++-v3/include/debug/macros.h b/libstdc++-v3/include/debug/macros.h
index 3df0c9bd31d..30606d5bf66 100644
--- a/libstdc++-v3/include/debug/macros.h
+++ b/libstdc++-v3/include/debug/macros.h
@@ -333,6 +333,11 @@ _GLIBCXX_DEBUG_VERIFY(_F > 0.0f, \
_M_message(__gnu_debug::__msg_valid_load_factor) \
._M_sequence(*this, "this"))
+#define __glibcxx_check_equal_allocs(_Other) \
+_GLIBCXX_DEBUG_VERIFY(this->get_allocator() == _Other.get_allocator(), \
+ _M_message(__gnu_debug::__msg_equal_allocs) \
+ ._M_sequence(*this, "this"))
+
#ifdef _GLIBCXX_DEBUG_PEDANTIC
# define __glibcxx_check_string(_String) _GLIBCXX_DEBUG_ASSERT(_String != 0)
# define __glibcxx_check_string_len(_String,_Len) \
diff --git a/libstdc++-v3/include/debug/vector b/libstdc++-v3/include/debug/vector
index 9e0f8439a12..9c33fdf69f9 100644
--- a/libstdc++-v3/include/debug/vector
+++ b/libstdc++-v3/include/debug/vector
@@ -550,6 +550,10 @@ namespace __debug
noexcept(_Alloc_traits::_S_nothrow_swap())
#endif
{
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ if (!_Alloc_traits::_S_propagate_on_swap())
+ __glibcxx_check_equal_allocs(__x);
+#endif
_Base::swap(__x);
this->_M_swap(__x);
std::swap(_M_guaranteed_capacity, __x._M_guaranteed_capacity);
diff --git a/libstdc++-v3/include/ext/throw_allocator.h b/libstdc++-v3/include/ext/throw_allocator.h
index 4988f8a8a15..8942232c825 100644
--- a/libstdc++-v3/include/ext/throw_allocator.h
+++ b/libstdc++-v3/include/ext/throw_allocator.h
@@ -1,7 +1,6 @@
// -*- C++ -*-
-// Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011
-// Free Software Foundation, Inc.
+// Copyright (C) 2005-2012 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -467,6 +466,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
throw_value_base(const throw_value_base& __v) : _M_i(__v._M_i)
{ throw_conditionally(); }
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ // Shall not throw.
+ throw_value_base(throw_value_base&&) = default;
+#endif
+
explicit throw_value_base(const std::size_t __i) : _M_i(__i)
{ throw_conditionally(); }
#endif
@@ -479,6 +483,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return *this;
}
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ // Shall not throw.
+ throw_value_base&
+ operator=(throw_value_base&&) = default;
+#endif
+
throw_value_base&
operator++()
{
@@ -568,8 +578,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
throw_value_limit(const throw_value_limit& __other)
: base_type(__other._M_i) { }
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ throw_value_limit(throw_value_limit&&) = default;
+#endif
+
explicit throw_value_limit(const std::size_t __i) : base_type(__i) { }
#endif
+
+ throw_value_limit&
+ operator=(const throw_value_limit& __other)
+ {
+ base_type::operator=(__other);
+ return *this;
+ }
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ throw_value_limit&
+ operator=(throw_value_limit&&) = default;
+#endif
};
/// Type throwing via random condition.
@@ -583,9 +609,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
throw_value_random(const throw_value_random& __other)
: base_type(__other._M_i) { }
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ throw_value_random(throw_value_random&&) = default;
+#endif
explicit throw_value_random(const std::size_t __i) : base_type(__i) { }
#endif
+
+ throw_value_random&
+ operator=(const throw_value_random& __other)
+ {
+ base_type::operator=(__other);
+ return *this;
+ }
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ throw_value_random&
+ operator=(throw_value_random&&) = default;
+#endif
};
diff --git a/libstdc++-v3/include/profile/deque b/libstdc++-v3/include/profile/deque
index 48a18c984d9..99cc46524a6 100644
--- a/libstdc++-v3/include/profile/deque
+++ b/libstdc++-v3/include/profile/deque
@@ -1,6 +1,6 @@
// Profiling deque implementation -*- C++ -*-
-// Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
+// Copyright (C) 2009-2012 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@@ -79,7 +79,12 @@ namespace __profile
: _Base(__n, __value, __a) { }
#endif
- template<class _InputIterator>
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ template<typename _InputIterator,
+ typename = std::_RequireInputIter<_InputIterator>>
+#else
+ template<typename _InputIterator>
+#endif
deque(_InputIterator __first, _InputIterator __last,
const _Allocator& __a = _Allocator())
: _Base(__first, __last, __a)
@@ -129,7 +134,12 @@ namespace __profile
}
#endif
- template<class _InputIterator>
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ template<typename _InputIterator,
+ typename = std::_RequireInputIter<_InputIterator>>
+#else
+ template<typename _InputIterator>
+#endif
void
assign(_InputIterator __first, _InputIterator __last)
{
@@ -343,7 +353,12 @@ namespace __profile
_Base::insert(__position, __n, __x);
}
- template<class _InputIterator>
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ template<typename _InputIterator,
+ typename = std::_RequireInputIter<_InputIterator>>
+#else
+ template<typename _InputIterator>
+#endif
void
insert(iterator __position,
_InputIterator __first, _InputIterator __last)
diff --git a/libstdc++-v3/include/profile/forward_list b/libstdc++-v3/include/profile/forward_list
index 618b2480caa..9cb58202f33 100644
--- a/libstdc++-v3/include/profile/forward_list
+++ b/libstdc++-v3/include/profile/forward_list
@@ -1,6 +1,6 @@
// <forward_list> -*- C++ -*-
-// Copyright (C) 2010, 2011 Free Software Foundation, Inc.
+// Copyright (C) 2010-2012 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@@ -46,10 +46,14 @@ namespace __profile
{
typedef _GLIBCXX_STD_C::forward_list<_Tp, _Alloc> _Base;
+ typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
+ rebind<_GLIBCXX_STD_C::_Fwd_list_node<_Tp>>::other _Node_alloc_type;
+
+ typedef __gnu_cxx::__alloc_traits<_Node_alloc_type> _Node_alloc_traits;
+
public:
typedef typename _Base::size_type size_type;
- public:
// 23.2.3.1 construct/copy/destroy:
explicit
forward_list(const _Alloc& __al = _Alloc())
@@ -64,8 +68,8 @@ namespace __profile
{ }
explicit
- forward_list(size_type __n)
- : _Base(__n)
+ forward_list(size_type __n, const _Alloc& __al = _Alloc())
+ : _Base(__n, __al)
{ }
forward_list(size_type __n, const _Tp& __value,
@@ -73,7 +77,8 @@ namespace __profile
: _Base(__n, __value, __al)
{ }
- template<typename _InputIterator>
+ template<typename _InputIterator,
+ typename = std::_RequireInputIter<_InputIterator>>
forward_list(_InputIterator __first, _InputIterator __last,
const _Alloc& __al = _Alloc())
: _Base(__first, __last, __al)
@@ -103,11 +108,9 @@ namespace __profile
forward_list&
operator=(forward_list&& __list)
+ noexcept(_Node_alloc_traits::_S_nothrow_move())
{
- // NB: DR 1204.
- // NB: DR 675.
- _Base::clear();
- _Base::swap(__list);
+ static_cast<_Base&>(*this) = std::move(__list);
return *this;
}
diff --git a/libstdc++-v3/include/profile/list b/libstdc++-v3/include/profile/list
index 33b1ae64d87..2f8535e946e 100644
--- a/libstdc++-v3/include/profile/list
+++ b/libstdc++-v3/include/profile/list
@@ -1,6 +1,6 @@
// Profiling list implementation -*- C++ -*-
-// Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
+// Copyright (C) 2009-2012 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@@ -99,7 +99,12 @@ template<typename _Tp, typename _Allocator = std::allocator<_Tp> >
}
#endif
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ template<typename _InputIterator,
+ typename = std::_RequireInputIter<_InputIterator>>
+#else
template<class _InputIterator>
+#endif
list(_InputIterator __first, _InputIterator __last,
const _Allocator& __a = _Allocator())
: _Base(__first, __last, __a)
@@ -171,7 +176,12 @@ template<typename _Tp, typename _Allocator = std::allocator<_Tp> >
{ _Base::assign(__l); }
#endif
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ template<typename _InputIterator,
+ typename = std::_RequireInputIter<_InputIterator>>
+#else
template<class _InputIterator>
+#endif
void
assign(_InputIterator __first, _InputIterator __last)
{ _Base::assign(__first, __last); }
@@ -328,7 +338,8 @@ template<typename _Tp, typename _Allocator = std::allocator<_Tp> >
emplace(iterator __position, _Args&&... __args)
{
return iterator(_Base::emplace(__position.base(),
- std::forward<_Args>(__args)...));
+ std::forward<_Args>(__args)...),
+ this);
}
#endif
@@ -363,14 +374,19 @@ template<typename _Tp, typename _Allocator = std::allocator<_Tp> >
_Base::insert(__position.base(), __n, __x);
}
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ template<typename _InputIterator,
+ typename = std::_RequireInputIter<_InputIterator>>
+#else
template<class _InputIterator>
+#endif
void
insert(iterator __position, _InputIterator __first,
_InputIterator __last)
- {
- _M_profile_insert(this, __position, size());
- _Base::insert(__position.base(), __first, __last);
- }
+ {
+ _M_profile_insert(this, __position, size());
+ _Base::insert(__position.base(), __first, __last);
+ }
iterator
erase(iterator __position)
diff --git a/libstdc++-v3/include/profile/map.h b/libstdc++-v3/include/profile/map.h
index dcc69313867..f96f18bab05 100644
--- a/libstdc++-v3/include/profile/map.h
+++ b/libstdc++-v3/include/profile/map.h
@@ -69,7 +69,12 @@ namespace __profile
: _Base(__comp, __a)
{ __profcxx_map_to_unordered_map_construct(this); }
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ template<typename _InputIterator,
+ typename = std::_RequireInputIter<_InputIterator>>
+#else
template<typename _InputIterator>
+#endif
map(_InputIterator __first, _InputIterator __last,
const _Compare& __comp = _Compare(),
const _Allocator& __a = _Allocator())
@@ -252,10 +257,11 @@ namespace __profile
emplace_hint(const_iterator __pos, _Args&&... __args)
{
size_type size_before = size();
- auto __res = _Base::emplace_hint(__pos.base(),
+ auto __res = _Base::emplace_hint(__pos,
std::forward<_Args>(__args)...);
__profcxx_map_to_unordered_map_insert(this, size_before,
size() - size_before);
+ return __res;
}
#endif
@@ -326,7 +332,12 @@ namespace __profile
}
#endif
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ template<typename _InputIterator,
+ typename = std::_RequireInputIter<_InputIterator>>
+#else
template<typename _InputIterator>
+#endif
void
insert(_InputIterator __first, _InputIterator __last)
{
diff --git a/libstdc++-v3/include/profile/multimap.h b/libstdc++-v3/include/profile/multimap.h
index 2268161365b..42662af363e 100644
--- a/libstdc++-v3/include/profile/multimap.h
+++ b/libstdc++-v3/include/profile/multimap.h
@@ -68,7 +68,12 @@ namespace __profile
const _Allocator& __a = _Allocator())
: _Base(__comp, __a) { }
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ template<typename _InputIterator,
+ typename = std::_RequireInputIter<_InputIterator>>
+#else
template<typename _InputIterator>
+#endif
multimap(_InputIterator __first, _InputIterator __last,
const _Compare& __comp = _Compare(),
const _Allocator& __a = _Allocator())
@@ -234,7 +239,12 @@ namespace __profile
std::forward<_Pair>(__x))); }
#endif
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ template<typename _InputIterator,
+ typename = std::_RequireInputIter<_InputIterator>>
+#else
template<typename _InputIterator>
+#endif
void
insert(_InputIterator __first, _InputIterator __last)
{ _Base::insert(__first, __last); }
diff --git a/libstdc++-v3/include/profile/multiset.h b/libstdc++-v3/include/profile/multiset.h
index f76b4fac6d8..358879726d9 100644
--- a/libstdc++-v3/include/profile/multiset.h
+++ b/libstdc++-v3/include/profile/multiset.h
@@ -1,6 +1,6 @@
// Profiling multiset implementation -*- C++ -*-
-// Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
+// Copyright (C) 2009-2012 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@@ -68,7 +68,12 @@ namespace __profile
const _Allocator& __a = _Allocator())
: _Base(__comp, __a) { }
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ template<typename _InputIterator,
+ typename = std::_RequireInputIter<_InputIterator>>
+#else
template<typename _InputIterator>
+#endif
multiset(_InputIterator __first, _InputIterator __last,
const _Compare& __comp = _Compare(),
const _Allocator& __a = _Allocator())
@@ -215,7 +220,12 @@ namespace __profile
{ return iterator(_Base::insert(__position, std::move(__x))); }
#endif
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ template<typename _InputIterator,
+ typename = std::_RequireInputIter<_InputIterator>>
+#else
template<typename _InputIterator>
+#endif
void
insert(_InputIterator __first, _InputIterator __last)
{ _Base::insert(__first, __last); }
diff --git a/libstdc++-v3/include/profile/set.h b/libstdc++-v3/include/profile/set.h
index c0aa180893f..5aadab8317c 100644
--- a/libstdc++-v3/include/profile/set.h
+++ b/libstdc++-v3/include/profile/set.h
@@ -1,6 +1,6 @@
// Profiling set implementation -*- C++ -*-
-// Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
+// Copyright (C) 2009-2012 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@@ -68,7 +68,12 @@ namespace __profile
const _Allocator& __a = _Allocator())
: _Base(__comp, __a) { }
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ template<typename _InputIterator,
+ typename = std::_RequireInputIter<_InputIterator>>
+#else
template<typename _InputIterator>
+#endif
set(_InputIterator __first, _InputIterator __last,
const _Compare& __comp = _Compare(),
const _Allocator& __a = _Allocator())
@@ -230,7 +235,12 @@ namespace __profile
{ return iterator(_Base::insert(__position, std::move(__x))); }
#endif
- template <typename _InputIterator>
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ template<typename _InputIterator,
+ typename = std::_RequireInputIter<_InputIterator>>
+#else
+ template<typename _InputIterator>
+#endif
void
insert(_InputIterator __first, _InputIterator __last)
{ _Base::insert(__first, __last); }
diff --git a/libstdc++-v3/include/profile/vector b/libstdc++-v3/include/profile/vector
index 8a3e681b847..fcd69627995 100644
--- a/libstdc++-v3/include/profile/vector
+++ b/libstdc++-v3/include/profile/vector
@@ -1,6 +1,6 @@
// Profiling vector implementation -*- C++ -*-
-// Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
+// Copyright (C) 2009-2012 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@@ -109,7 +109,12 @@ namespace __profile
}
#endif
- template<class _InputIterator>
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ template<typename _InputIterator,
+ typename = std::_RequireInputIter<_InputIterator>>
+#else
+ template<typename _InputIterator>
+#endif
vector(_InputIterator __first, _InputIterator __last,
const _Allocator& __a = _Allocator())
: _Base(__first, __last, __a)
@@ -401,7 +406,12 @@ namespace __profile
_M_profile_resize(this, __old_size, this->capacity());
}
- template<class _InputIterator>
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ template<typename _InputIterator,
+ typename = std::_RequireInputIter<_InputIterator>>
+#else
+ template<typename _InputIterator>
+#endif
void
insert(iterator __position,
_InputIterator __first, _InputIterator __last)
diff --git a/libstdc++-v3/include/std/atomic b/libstdc++-v3/include/std/atomic
index 535a90f582e..4f9cd5035a3 100644
--- a/libstdc++-v3/include/std/atomic
+++ b/libstdc++-v3/include/std/atomic
@@ -1,6 +1,6 @@
// -*- C++ -*- header.
-// Copyright (C) 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
+// Copyright (C) 2008-2012 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@@ -184,11 +184,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
bool
is_lock_free() const noexcept
- { return __atomic_is_lock_free(sizeof(_M_i), NULL); }
+ { return __atomic_is_lock_free(sizeof(_M_i), nullptr); }
bool
is_lock_free() const volatile noexcept
- { return __atomic_is_lock_free(sizeof(_M_i), NULL); }
+ { return __atomic_is_lock_free(sizeof(_M_i), nullptr); }
void
store(_Tp __i, memory_order _m = memory_order_seq_cst) noexcept
diff --git a/libstdc++-v3/include/tr2/dynamic_bitset b/libstdc++-v3/include/tr2/dynamic_bitset
index 53b696f0ebd..5ea0ea5dc7d 100644
--- a/libstdc++-v3/include/tr2/dynamic_bitset
+++ b/libstdc++-v3/include/tr2/dynamic_bitset
@@ -33,7 +33,6 @@
#include <limits>
#include <vector>
-#include <cstddef> // For size_t
#include <string>
#include <memory> // For std::allocator
#include <bits/functexcept.h> // For invalid_argument, out_of_range,
diff --git a/libstdc++-v3/libsupc++/vec.cc b/libstdc++-v3/libsupc++/vec.cc
index f9afd39df9b..507514ec76a 100644
--- a/libstdc++-v3/libsupc++/vec.cc
+++ b/libstdc++-v3/libsupc++/vec.cc
@@ -28,6 +28,7 @@
#include <cxxabi.h>
#include <new>
#include <exception>
+#include <cstdlib>
#include <bits/exception_defines.h>
#include "unwind-cxx.h"
@@ -65,10 +66,18 @@ namespace __cxxabiv1
std::size_t padding_size)
{
if (element_size && element_count > std::size_t(-1) / element_size)
+#ifdef __EXCEPTIONS
throw std::bad_alloc();
+#else
+ std::abort();
+#endif
std::size_t size = element_count * element_size;
if (size + padding_size < size)
+#ifdef __EXCEPTIONS
throw std::bad_alloc();
+#else
+ std::abort();
+#endif
return size + padding_size;
}
}
diff --git a/libstdc++-v3/src/c++11/debug.cc b/libstdc++-v3/src/c++11/debug.cc
index 8a18026a44e..f7725ed50db 100644
--- a/libstdc++-v3/src/c++11/debug.cc
+++ b/libstdc++-v3/src/c++11/debug.cc
@@ -181,7 +181,8 @@ namespace __gnu_debug
"attempt to self move assign",
"attempt to access container with out-of-bounds bucket index %2;,"
" container only holds %3; buckets",
- "load factor shall be positive"
+ "load factor shall be positive",
+ "allocators must be equal"
};
void
diff --git a/libstdc++-v3/testsuite/23_containers/deque/requirements/exception/propagation_consistent.cc b/libstdc++-v3/testsuite/23_containers/deque/requirements/exception/propagation_consistent.cc
index 14892344e9f..320084c926b 100644
--- a/libstdc++-v3/testsuite/23_containers/deque/requirements/exception/propagation_consistent.cc
+++ b/libstdc++-v3/testsuite/23_containers/deque/requirements/exception/propagation_consistent.cc
@@ -1,10 +1,9 @@
// { dg-options "-std=gnu++0x" }
// { dg-require-cstdint "" }
-// { dg-do run { xfail *-*-* } }
// 2009-09-09 Benjamin Kosnik <benjamin@redhat.com>
-// Copyright (C) 2009 Free Software Foundation, Inc.
+// Copyright (C) 2009-2012 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/allocator/swap.cc b/libstdc++-v3/testsuite/23_containers/forward_list/allocator/swap.cc
index 60d83d4507b..1d1e217f152 100644
--- a/libstdc++-v3/testsuite/23_containers/forward_list/allocator/swap.cc
+++ b/libstdc++-v3/testsuite/23_containers/forward_list/allocator/swap.cc
@@ -25,6 +25,23 @@ struct T { int i; };
using __gnu_test::propagating_allocator;
+// It is undefined behaviour to swap() containers wth unequal allocators
+// if the allocator doesn't propagate, so ensure the allocators compare
+// equal, while still being able to test propagation via get_personality().
+bool
+operator==(const propagating_allocator<T, false>&,
+ const propagating_allocator<T, false>&)
+{
+ return true;
+}
+
+bool
+operator!=(const propagating_allocator<T, false>&,
+ const propagating_allocator<T, false>&)
+{
+ return false;
+}
+
void test01()
{
bool test __attribute__((unused)) = true;
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/insert/55028-debug.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/insert/55028-debug.cc
new file mode 100644
index 00000000000..fc17256f4bb
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_multimap/insert/55028-debug.cc
@@ -0,0 +1,40 @@
+// { dg-options "-std=gnu++0x -D_GLIBCXX_DEBUG" }
+//
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// libstdc++/55028
+#include <string>
+#include <unordered_map>
+#include <testsuite_hooks.h>
+
+struct MyType
+{ };
+
+void test()
+{
+ // using MyMap = std::multimap<std::string, MyType *>; // works
+ using MyMap = std::unordered_multimap<std::string, MyType*>; // fails to link
+ MyMap m;
+ m.insert(std::make_pair(std::string("blah"), new MyType));
+}
+
+int main()
+{
+ test();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/vector/allocator/swap.cc b/libstdc++-v3/testsuite/23_containers/vector/allocator/swap.cc
index 808753e7520..2ca19db1713 100644
--- a/libstdc++-v3/testsuite/23_containers/vector/allocator/swap.cc
+++ b/libstdc++-v3/testsuite/23_containers/vector/allocator/swap.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2011 Free Software Foundation
+// Copyright (C) 2011-2012 Free Software Foundation
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@@ -25,6 +25,23 @@ struct T { int i; };
using __gnu_test::propagating_allocator;
+// It is undefined behaviour to swap() containers wth unequal allocators
+// if the allocator doesn't propagate, so ensure the allocators compare
+// equal, while still being able to test propagation via get_personality().
+bool
+operator==(const propagating_allocator<T, false>&,
+ const propagating_allocator<T, false>&)
+{
+ return true;
+}
+
+bool
+operator!=(const propagating_allocator<T, false>&,
+ const propagating_allocator<T, false>&)
+{
+ return false;
+}
+
void test01()
{
bool test __attribute__((unused)) = true;
diff --git a/libstdc++-v3/testsuite/26_numerics/random/discard_block_engine/cons/55215.cc b/libstdc++-v3/testsuite/26_numerics/random/discard_block_engine/cons/55215.cc
new file mode 100644
index 00000000000..c655b262062
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/random/discard_block_engine/cons/55215.cc
@@ -0,0 +1,58 @@
+// { dg-options "-std=gnu++11" }
+// { dg-require-cstdint "" }
+//
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <random>
+#include <testsuite_hooks.h>
+
+int f(int x)
+{
+ std::seed_seq sq(&x, &x + 1);
+ auto rnd = std::ranlux24(sq);
+ return std::uniform_int_distribution<int>()(rnd);
+}
+
+int g(int x)
+{
+ std::seed_seq sq(&x, &x + 1);
+ auto rnd = std::ranlux24();
+ rnd.seed(sq);
+ return std::uniform_int_distribution<int>()(rnd);
+}
+
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ const int f1 = f(0);
+ const int f2 = f(0);
+
+ const int g1 = g(0);
+ const int g2 = g(0);
+
+ VERIFY( f1 == f2 );
+ VERIFY( g1 == g2 );
+ VERIFY( f1 == g1 );
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/26_numerics/random/independent_bits_engine/cons/55215.cc b/libstdc++-v3/testsuite/26_numerics/random/independent_bits_engine/cons/55215.cc
new file mode 100644
index 00000000000..4b502b7d7c0
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/random/independent_bits_engine/cons/55215.cc
@@ -0,0 +1,60 @@
+// { dg-options "-std=gnu++11" }
+// { dg-require-cstdint "" }
+//
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <random>
+#include <testsuite_hooks.h>
+
+int f(int x)
+{
+ std::seed_seq sq(&x, &x + 1);
+ auto rnd = std::independent_bits_engine<std::mt19937, 9,
+ std::uint_fast32_t>(sq);
+ return std::uniform_int_distribution<int>()(rnd);
+}
+
+int g(int x)
+{
+ std::seed_seq sq(&x, &x + 1);
+ auto rnd = std::independent_bits_engine<std::mt19937, 9,
+ std::uint_fast32_t>();
+ rnd.seed(sq);
+ return std::uniform_int_distribution<int>()(rnd);
+}
+
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ const int f1 = f(0);
+ const int f2 = f(0);
+
+ const int g1 = g(0);
+ const int g2 = g(0);
+
+ VERIFY( f1 == f2 );
+ VERIFY( g1 == g2 );
+ VERIFY( f1 == g1 );
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/26_numerics/random/linear_congruential_engine/cons/55215.cc b/libstdc++-v3/testsuite/26_numerics/random/linear_congruential_engine/cons/55215.cc
new file mode 100644
index 00000000000..21333fba97d
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/random/linear_congruential_engine/cons/55215.cc
@@ -0,0 +1,58 @@
+// { dg-options "-std=gnu++11" }
+// { dg-require-cstdint "" }
+//
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <random>
+#include <testsuite_hooks.h>
+
+int f(int x)
+{
+ std::seed_seq sq(&x, &x + 1);
+ auto rnd = std::minstd_rand(sq);
+ return std::uniform_int_distribution<int>()(rnd);
+}
+
+int g(int x)
+{
+ std::seed_seq sq(&x, &x + 1);
+ auto rnd = std::minstd_rand();
+ rnd.seed(sq);
+ return std::uniform_int_distribution<int>()(rnd);
+}
+
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ const int f1 = f(0);
+ const int f2 = f(0);
+
+ const int g1 = g(0);
+ const int g2 = g(0);
+
+ VERIFY( f1 == f2 );
+ VERIFY( g1 == g2 );
+ VERIFY( f1 == g1 );
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/26_numerics/random/mersenne_twister_engine/cons/55215.cc b/libstdc++-v3/testsuite/26_numerics/random/mersenne_twister_engine/cons/55215.cc
new file mode 100644
index 00000000000..3453d9f727a
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/random/mersenne_twister_engine/cons/55215.cc
@@ -0,0 +1,58 @@
+// { dg-options "-std=gnu++11" }
+// { dg-require-cstdint "" }
+//
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <random>
+#include <testsuite_hooks.h>
+
+int f(int x)
+{
+ std::seed_seq sq(&x, &x + 1);
+ auto rnd = std::mt19937(sq);
+ return std::uniform_int_distribution<int>()(rnd);
+}
+
+int g(int x)
+{
+ std::seed_seq sq(&x, &x + 1);
+ auto rnd = std::mt19937();
+ rnd.seed(sq);
+ return std::uniform_int_distribution<int>()(rnd);
+}
+
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ const int f1 = f(0);
+ const int f2 = f(0);
+
+ const int g1 = g(0);
+ const int g2 = g(0);
+
+ VERIFY( f1 == f2 );
+ VERIFY( g1 == g2 );
+ VERIFY( f1 == g1 );
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/26_numerics/random/shuffle_order_engine/cons/55215.cc b/libstdc++-v3/testsuite/26_numerics/random/shuffle_order_engine/cons/55215.cc
new file mode 100644
index 00000000000..d7db635d8ef
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/random/shuffle_order_engine/cons/55215.cc
@@ -0,0 +1,58 @@
+// { dg-options "-std=gnu++11" }
+// { dg-require-cstdint "" }
+//
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <random>
+#include <testsuite_hooks.h>
+
+int f(int x)
+{
+ std::seed_seq sq(&x, &x + 1);
+ auto rnd = std::knuth_b(sq);
+ return std::uniform_int_distribution<int>()(rnd);
+}
+
+int g(int x)
+{
+ std::seed_seq sq(&x, &x + 1);
+ auto rnd = std::knuth_b();
+ rnd.seed(sq);
+ return std::uniform_int_distribution<int>()(rnd);
+}
+
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ const int f1 = f(0);
+ const int f2 = f(0);
+
+ const int g1 = g(0);
+ const int g2 = g(0);
+
+ VERIFY( f1 == f2 );
+ VERIFY( g1 == g2 );
+ VERIFY( f1 == g1 );
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/26_numerics/random/subtract_with_carry_engine/cons/55215.cc b/libstdc++-v3/testsuite/26_numerics/random/subtract_with_carry_engine/cons/55215.cc
new file mode 100644
index 00000000000..4927d771667
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/random/subtract_with_carry_engine/cons/55215.cc
@@ -0,0 +1,58 @@
+// { dg-options "-std=gnu++11" }
+// { dg-require-cstdint "" }
+//
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <random>
+#include <testsuite_hooks.h>
+
+int f(int x)
+{
+ std::seed_seq sq(&x, &x + 1);
+ auto rnd = std::ranlux24_base(sq);
+ return std::uniform_int_distribution<int>()(rnd);
+}
+
+int g(int x)
+{
+ std::seed_seq sq(&x, &x + 1);
+ auto rnd = std::ranlux24_base();
+ rnd.seed(sq);
+ return std::uniform_int_distribution<int>()(rnd);
+}
+
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ const int f1 = f(0);
+ const int f2 = f(0);
+
+ const int g1 = g(0);
+ const int g2 = g(0);
+
+ VERIFY( f1 == f2 );
+ VERIFY( g1 == g2 );
+ VERIFY( f1 == g1 );
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/util/exception/safety.h b/libstdc++-v3/testsuite/util/exception/safety.h
index 50418983ca6..12f41c140fa 100644
--- a/libstdc++-v3/testsuite/util/exception/safety.h
+++ b/libstdc++-v3/testsuite/util/exception/safety.h
@@ -1,6 +1,6 @@
// -*- C++ -*-
-// Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+// Copyright (C) 2009-2012 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -226,17 +226,22 @@ namespace __gnu_test
// compared to the control container.
// NB: Should be equivalent to __test != __control, but
// computed without equivalence operators
- const size_type szt = std::distance(__test.begin(), __test.end());
- const size_type szc = std::distance(__control.begin(),
- __control.end());
- bool __equal_size = szt == szc;
+ const size_type szt
+ = std::distance(__test.begin(), __test.end());
+ const size_type szc
+ = std::distance(__control.begin(), __control.end());
+
+ if (szt != szc)
+ throw std::logic_error(
+ "setup_base::compare containers size not equal");
// Should test iterator validity before and after exception.
bool __equal_it = std::equal(__test.begin(), __test.end(),
__control.begin());
- if (!__equal_size || !__equal_it)
- throw std::logic_error("setup_base::compare containers not equal");
+ if (!__equal_it)
+ throw std::logic_error(
+ "setup_base::compare containers iterators not equal");
return true;
}
@@ -627,6 +632,96 @@ namespace __gnu_test
operator()(_Tp&, _Tp&) { }
};
+ template<typename _Tp, bool = traits<_Tp>::has_push_pop::value
+ && traits<_Tp>::has_emplace::value>
+ struct emplace_front
+ {
+ typedef _Tp container_type;
+ typedef typename container_type::value_type value_type;
+
+ void
+ operator()(_Tp& __test)
+ {
+ try
+ {
+ const value_type cv = generate_unique<value_type>();
+ __test.emplace_front(cv);
+ }
+ catch(const __gnu_cxx::forced_error&)
+ { throw; }
+ }
+
+ // Assumes containers start out equivalent.
+ void
+ operator()(_Tp& __control, _Tp& __test)
+ {
+ try
+ {
+ const value_type cv = generate_unique<value_type>();
+ __test.emplace_front(cv);
+ }
+ catch(const __gnu_cxx::forced_error&)
+ { throw; }
+ }
+ };
+
+ // Specialization, empty.
+ template<typename _Tp>
+ struct emplace_front<_Tp, false>
+ {
+ void
+ operator()(_Tp&) { }
+
+ void
+ operator()(_Tp&, _Tp&) { }
+ };
+
+
+ template<typename _Tp, bool = traits<_Tp>::has_push_pop::value
+ && traits<_Tp>::has_emplace::value
+ && traits<_Tp>::is_reversible::value>
+ struct emplace_back
+ {
+ typedef _Tp container_type;
+ typedef typename container_type::value_type value_type;
+
+ void
+ operator()(_Tp& __test)
+ {
+ try
+ {
+ const value_type cv = generate_unique<value_type>();
+ __test.emplace_back(cv);
+ }
+ catch(const __gnu_cxx::forced_error&)
+ { throw; }
+ }
+
+ // Assumes containers start out equivalent.
+ void
+ operator()(_Tp& __control, _Tp& __test)
+ {
+ try
+ {
+ const value_type cv = generate_unique<value_type>();
+ __test.push_back(cv);
+ }
+ catch(const __gnu_cxx::forced_error&)
+ { throw; }
+ }
+ };
+
+ // Specialization, empty.
+ template<typename _Tp>
+ struct emplace_back<_Tp, false>
+ {
+ void
+ operator()(_Tp&) { }
+
+ void
+ operator()(_Tp&, _Tp&) { }
+ };
+
// Abstract the insert function into two parts:
// 1, insert_base_functions == holds function pointer
@@ -726,9 +821,8 @@ namespace __gnu_test
insert_base() : _F_insert_point(&container_type::insert_after) { }
};
- template<typename _Tp,
- bool = traits<_Tp>::has_insert::value,
- bool = traits<_Tp>::has_insert_after::value>
+ template<typename _Tp, bool = traits<_Tp>::has_insert::value,
+ bool = traits<_Tp>::has_insert_after::value>
struct insert_point;
// Specialization for most containers.
@@ -826,11 +920,12 @@ namespace __gnu_test
operator()(_Tp&, _Tp&) { }
};
- template<typename _Tp,
- bool = traits<_Tp>::has_emplace::value>
+ template<typename _Tp, bool = traits<_Tp>::has_emplace::value
+ && (traits<_Tp>::is_associative::value
+ || traits<_Tp>::is_unordered::value)>
struct emplace;
- // Specialization for most containers.
+ // Specialization for associative and unordered containers.
template<typename _Tp>
struct emplace<_Tp, true>
{
@@ -875,13 +970,56 @@ namespace __gnu_test
operator()(_Tp&, _Tp&) { }
};
- template<typename _Tp,
- bool = traits<_Tp>::has_emplace::value>
- struct emplace_hint;
+ template<typename _Tp, bool = traits<_Tp>::has_emplace::value,
+ bool = traits<_Tp>::is_associative::value
+ || traits<_Tp>::is_unordered::value,
+ bool = traits<_Tp>::has_insert_after::value>
+ struct emplace_point;
// Specialization for most containers.
template<typename _Tp>
- struct emplace_hint<_Tp, true>
+ struct emplace_point<_Tp, true, false, false>
+ {
+ typedef _Tp container_type;
+ typedef typename container_type::value_type value_type;
+
+ void
+ operator()(_Tp& __test)
+ {
+ try
+ {
+ const value_type cv = generate_unique<value_type>();
+ const size_type sz = std::distance(__test.begin(), __test.end());
+ size_type s = generate(sz);
+ auto i = __test.begin();
+ std::advance(i, s);
+ __test.emplace(i, cv);
+ }
+ catch(const __gnu_cxx::forced_error&)
+ { throw; }
+ }
+
+ // Assumes containers start out equivalent.
+ void
+ operator()(_Tp& __control, _Tp& __test)
+ {
+ try
+ {
+ const value_type cv = generate_unique<value_type>();
+ const size_type sz = std::distance(__test.begin(), __test.end());
+ size_type s = generate(sz);
+ auto i = __test.begin();
+ std::advance(i, s);
+ __test.emplace(i, cv);
+ }
+ catch(const __gnu_cxx::forced_error&)
+ { throw; }
+ }
+ };
+
+ // Specialization for associative and unordered containers.
+ template<typename _Tp>
+ struct emplace_point<_Tp, true, true, false>
{
typedef _Tp container_type;
typedef typename container_type::value_type value_type;
@@ -920,9 +1058,52 @@ namespace __gnu_test
}
};
- // Specialization, empty.
+ // Specialization for forward_list.
template<typename _Tp>
- struct emplace_hint<_Tp, false>
+ struct emplace_point<_Tp, true, false, true>
+ {
+ typedef _Tp container_type;
+ typedef typename container_type::value_type value_type;
+
+ void
+ operator()(_Tp& __test)
+ {
+ try
+ {
+ const value_type cv = generate_unique<value_type>();
+ const size_type sz = std::distance(__test.begin(), __test.end());
+ size_type s = generate(sz);
+ auto i = __test.before_begin();
+ std::advance(i, s);
+ __test.emplace_after(i, cv);
+ }
+ catch(const __gnu_cxx::forced_error&)
+ { throw; }
+ }
+
+ // Assumes containers start out equivalent.
+ void
+ operator()(_Tp& __control, _Tp& __test)
+ {
+ try
+ {
+ const value_type cv = generate_unique<value_type>();
+ const size_type sz = std::distance(__test.begin(), __test.end());
+ size_type s = generate(sz);
+ auto i = __test.before_begin();
+ std::advance(i, s);
+ __test.emplace_after(i, cv);
+ }
+ catch(const __gnu_cxx::forced_error&)
+ { throw; }
+ }
+ };
+
+ // Specialization, empty.
+ template<typename _Tp, bool is_associative_or_unordered,
+ bool has_insert_after>
+ struct emplace_point<_Tp, false, is_associative_or_unordered,
+ has_insert_after>
{
void
operator()(_Tp&) { }
@@ -1128,7 +1309,9 @@ namespace __gnu_test
typedef erase_range<container_type> erase_range;
typedef insert_point<container_type> insert_point;
typedef emplace<container_type> emplace;
- typedef emplace_hint<container_type> emplace_hint;
+ typedef emplace_point<container_type> emplace_point;
+ typedef emplace_front<container_type> emplace_front;
+ typedef emplace_back<container_type> emplace_back;
typedef pop_front<container_type> pop_front;
typedef pop_back<container_type> pop_back;
typedef push_front<container_type> push_front;
@@ -1146,7 +1329,9 @@ namespace __gnu_test
erase_range _M_eraser;
insert_point _M_insertp;
emplace _M_emplace;
- emplace_hint _M_emplaceh;
+ emplace_point _M_emplacep;
+ emplace_front _M_emplacef;
+ emplace_back _M_emplaceb;
pop_front _M_popf;
pop_back _M_popb;
push_front _M_pushf;
@@ -1207,7 +1392,9 @@ namespace __gnu_test
_M_functions.push_back(function_type(base_type::_M_eraser));
_M_functions.push_back(function_type(base_type::_M_insertp));
_M_functions.push_back(function_type(base_type::_M_emplace));
- _M_functions.push_back(function_type(base_type::_M_emplaceh));
+ _M_functions.push_back(function_type(base_type::_M_emplacep));
+ _M_functions.push_back(function_type(base_type::_M_emplacef));
+ _M_functions.push_back(function_type(base_type::_M_emplaceb));
_M_functions.push_back(function_type(base_type::_M_popf));
_M_functions.push_back(function_type(base_type::_M_popb));
_M_functions.push_back(function_type(base_type::_M_pushf));
@@ -1328,7 +1515,8 @@ namespace __gnu_test
// Test strong exception guarantee.
// Run through all member functions with a roll-back, consistent
// coherent requirement.
- // all: member functions insert of a single element, push_back, push_front
+ // all: member functions insert and emplace of a single element, push_back,
+ // push_front
// unordered: rehash
template<typename _Tp>
struct propagation_consistent : public test_base<_Tp>
@@ -1360,9 +1548,12 @@ namespace __gnu_test
// Construct containers.
populate p(_M_container_control);
- sync();
// Construct list of member functions to exercise.
+ _M_functions.push_back(function_type(base_type::_M_emplace));
+ _M_functions.push_back(function_type(base_type::_M_emplacep));
+ _M_functions.push_back(function_type(base_type::_M_emplacef));
+ _M_functions.push_back(function_type(base_type::_M_emplaceb));
_M_functions.push_back(function_type(base_type::_M_pushf));
_M_functions.push_back(function_type(base_type::_M_pushb));
_M_functions.push_back(function_type(base_type::_M_insertp));
diff --git a/libstdc++-v3/testsuite/util/testsuite_container_traits.h b/libstdc++-v3/testsuite/util/testsuite_container_traits.h
index 5d8aae04fe0..2e253b96a21 100644
--- a/libstdc++-v3/testsuite/util/testsuite_container_traits.h
+++ b/libstdc++-v3/testsuite/util/testsuite_container_traits.h
@@ -1,6 +1,6 @@
// -*- C++ -*-
-// Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+// Copyright (C) 2009-2012 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -73,6 +73,7 @@ namespace __gnu_test
typedef std::true_type has_insert;
typedef std::true_type has_push_pop;
typedef std::true_type has_size_type_constructor;
+ typedef std::true_type has_emplace;
};
template<typename _Tp1, typename _Tp2>
@@ -85,6 +86,7 @@ namespace __gnu_test
typedef std::true_type has_insert_after;
typedef std::true_type has_push_pop;
typedef std::true_type has_size_type_constructor;
+ typedef std::true_type has_emplace;
};
template<typename _Tp1, typename _Tp2>
@@ -98,6 +100,7 @@ namespace __gnu_test
typedef std::true_type has_insert;
typedef std::true_type has_push_pop;
typedef std::true_type has_size_type_constructor;
+ typedef std::true_type has_emplace;
};
template<typename _Tp1, typename _Tp2>
@@ -111,6 +114,7 @@ namespace __gnu_test
typedef std::true_type has_throwing_erase;
typedef std::true_type has_insert;
typedef std::true_type has_size_type_constructor;
+ typedef std::true_type has_emplace;
};
template<typename _Tp1, typename _Tp2, typename _Tp3>
@@ -148,9 +152,7 @@ namespace __gnu_test
typedef std::true_type has_erase;
typedef std::true_type has_insert;
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
typedef std::true_type has_emplace;
-#endif
};
template<typename _Tp1, typename _Tp2, typename _Tp3, typename _Tp4>
@@ -164,9 +166,7 @@ namespace __gnu_test
typedef std::true_type has_erase;
typedef std::true_type has_insert;
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
typedef std::true_type has_emplace;
-#endif
};
template<typename _Tp1, typename _Tp2, typename _Tp3>
@@ -179,9 +179,7 @@ namespace __gnu_test
typedef std::true_type has_erase;
typedef std::true_type has_insert;
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
typedef std::true_type has_emplace;
-#endif
};
template<typename _Tp1, typename _Tp2, typename _Tp3>
@@ -194,9 +192,7 @@ namespace __gnu_test
typedef std::true_type has_erase;
typedef std::true_type has_insert;
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
typedef std::true_type has_emplace;
-#endif
};
template<typename _Tp1, typename _Tp2>