diff options
author | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-10-10 06:10:28 +0000 |
---|---|---|
committer | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-10-10 06:10:28 +0000 |
commit | 25524fa163374223fba10886994be16859209590 (patch) | |
tree | a2ea2f2478904badddf849a74af13183554de44b /gcc | |
parent | 2269ca4e4e02754a2d686c6b7b027f1f3918b3c5 (diff) | |
download | gcc-25524fa163374223fba10886994be16859209590.tar.gz |
2011-10-10 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk rev 179735 using svnmerge.
gcc/
2011-10-10 Basile Starynkevitch <basile@starynkevitch.net>
* melt-runtime.h (meltppbuffer, meltppbufsiz): Declare as extern
variables.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@179736 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
238 files changed, 4415 insertions, 2310 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4e459f40a8f..3a3c9853a16 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,340 @@ +2011-10-09 Eric Botcazou <ebotcazou@adacore.com> + + * tree-ssa-forwprop.c (forward_propagate_into_comparison): Do not make + the replacement if the conversion to the LHS type is not useless. + +2011-10-09 Ira Rosen <ira.rosen@linaro.org> + + PR tree-optimization/50635 + * tree-vect-patterns.c (vect_handle_widen_mult_by_const): Add + DEF_STMT to the list of statements to be replaced by the + pattern statements. + (vect_handle_widen_mult_by_const): Don't check TYPE_OUT. + +2011-10-09 Anatoly Sokolov <aesok@post.ru> + + * system.h: Commit forgotten hunk in previous patch. + (OUTPUT_ADDR_CONST_EXTRA): Poison. + +2011-10-08 Nicola Pero <nicola.pero@meta-innovation.com> + + PR libobjc/50428 + * doc/objc.texi (Garbage Collection): Updated example to protect + +initialize against execution in subclasses. + +2011-10-07 Richard Henderson <rth@redhat.com> + + * doc/extend.texi (__builtin_shuffle): Improve the description to + include the modulus of the selector. Mention OpenCL. + * doc/md.texi (vec_perm, vec_perm_const): Document named patterns. + + * tree.def (VEC_PERM_EXPR): Rename from VEC_SHUFFLE_EXPR. + * genopinit.c (optabs): Rename vshuffle to vec_perm. + * c-typeck.c (c_build_vec_perm_expr): Rename from + c_build_vec_shuffle_expr. Update for name changes. + * optabs.c (expand_vec_perm_expr_p): Rename from + expand_vec_shuffle_expr_p. + (expand_vec_perm_expr): Rename from expand_vec_shuffle_expr. + * optabs.h (OTI_vec_perm): Rename from DOI_vshuffle. + (vec_perm_optab): Rename from vshuffle_optab. + * expr.c, gimple-pretty-print.c, gimple.c, gimplify.c, + c-tree.h, c-parser.c, tree-cfg.c, tree-inline.c, tree-pretty-print.c, + tree-ssa-operands.c, tree-vect-generic.c: Update for name changes. + + * config/i386/i386.c (ix86_expand_vec_perm): Rename from + ix86_expand_vshuffle. + * config/i386/i386-protos.h: Update. + * config/i386/sse.md (VEC_PERM_AVX2): Rename from VSHUFFLE_AVX2. + (vec_perm<VEC_PERM_AVX2>): Rename from vshuffle<VSHUFFLE_AVX2>. + +2011-10-07 Richard Henderson <rth@redhat.com> + + * config/i386/predicates.md (avx2_pblendw_operand): New. + * config/i386/sse.md (sse4_1_pblendw): Un-macroize. + (avx2_pblendw, *avx2_pblendw): New expander and insn. + +2011-10-07 Richard Henderson <rth@redhat.com> + + * config/i386/i386.c (bdesc_args): Update code for + __builtin_ia32_palignr256. Change type of __builtin_ia32_pslldqi256, + and __builtin_ia32_psrldqi256 to V4DI_FTYPE_V4DI_INT_CONVERT. + (ix86_expand_args_builtin): Handle V4DI_FTYPE_V4DI_INT_CONVERT. + * config/i386/sse.md (mode iterator V16): Add V2TI. + (mode iterator SSESCALARMODE): Use V2TI not V4DI. + (mode attr ssse3_avx2): Add V2TI. + (avx2_lshrqv4di3, avx2_lshlqv4di3): Remove. + +2011-10-07 David S. Miller <davem@davemloft.net> + + PR 50655 + * configure.ac: Add .register directives to VIS3 test. + * configure: Regenerate. + +2011-10-07 Richard Henderson <rth@redhat.com> + + * config.gcc (x86_64-*): Add core-avx-i, core-avx2 for with_cpu. + +2011-10-07 Richard Henderson <rth@redhat.com> + + PR 49752 + * fold-const.c (fold_checksum_tree): Remove out-of-date assert. + +2011-10-07 Andrew Stubbs <ams@codesourcery.com> + + * config/arm/predicates.md (shift_amount_operand): Remove constant + range check. + (shift_operator): Check range of constants for all shift operators. + +2011-10-07 Andreas Krebbel <Andreas.Krebbel@de.ibm.com> + + * config/s390/s390.c (s390_emit_tls_call_insn): Remove assertion. + Load GOT pointer for non-pic builds. + (s390_load_got): Replace pic_offset_table_rtx with hardcoded r12. + (s390_emit_call): Likewise. + +2011-10-07 Tom de Vries <tom@codesourcery.com> + + PR middle-end/50527 + * tree.c (build_common_builtin_nodes): Add local_define_builtin for + * builtins.c (expand_builtin_alloca): Handle BUILT_IN_ALLOCA_WITH_ALIGN + * tree-ssa-ccp.c (evaluate_stmt): Set align for + * builtins.def (BUILT_IN_ALLOCA_WITH_ALIGN): Declare using + * ipa-pure-const.c (special_builtin_state): Handle + * tree-ssa-alias.c (ref_maybe_used_by_call_p_1) + * function.c (gimplify_parameters): Lower vla to + * gimplify.c (gimplify_vla_decl): Same. + * cfgexpand.c (expand_call_stmt): Handle BUILT_IN_ALLOCA_WITH_ALIGN. + * tree-mudflap.c (mf_xform_statements): Same. + * tree-ssa-dce.c (mark_stmt_if_obviously_necessary) + * varasm.c (incorporeal_function_p): Same. + * tree-object-size.c (alloc_object_size): Same. + * gimple.c (gimple_build_call_from_tree): Same. + +2011-10-07 Bernd Schmidt <bernds@codesourcery.com> + + * function.c (frame_required_for_rtx): Remove function. + (requires_stack_frame_p): New arg set_up_by_prologue. All callers + changed. Compute a set of mentioned registers and compare against + the new arg rather than calling frame_required_for_rtx. + (thread_prologue_and_epilogue_insns): Compute the set_up_by_prologue + reg set. Convert the unconverted_simple_returns mechanism to store + jump insns rather than their basic blocks. Also check the + orig_entry_edge destination for new blocks. + +2011-10-07 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/50650 + * tree-vect-patterns.c (vect_recog_mixed_size_cond_pattern): Don't + call vect_is_simple_cond here, instead fail if cond_expr isn't + COMPARISON_CLASS_P or if get_vectype_for_scalar_type returns NULL + for cond_expr's first operand. + * tree-vect-stmts.c (vect_is_simple_cond): Static again. + * tree-vectorizer.h (vect_is_simple_cond): Remove prototype. + +2011-10-07 Andreas Krebbel <Andreas.Krebbel@de.ibm.com> + + * config/s390/s390.md (DWH, dwh): New mode macros. + ("umulsidi3"): Extend to support "umulditi3" as well. + +2011-10-07 Uros Bizjak <ubizjak@gmail.com> + H.J. Lu <hongjiu.lu@intel.com> + + PR target/50603 + * config/i386/i386.c (ix86_fixup_binary_operands): Force src2 of + integer PLUS RTX to a register to improve address combine. + +2011-10-06 Richard Henderson <rth@redhat.com> + + * combine-stack-adjust.c (maybe_move_args_size_note): Add after + parameter; use it to decide whether to merge two notes. + (combine_stack_adjustments_for_block): Use maybe_move_args_size_note + for the deallocation case as well. + +2011-10-06 Anatoly Sokolov <aesok@post.ru> + + * system.h (OUTPUT_ADDR_CONST_EXTRA): Poison. + * doc/tm.texi.in (OUTPUT_ADDR_CONST_EXTRA): Remove documentation. + * doc/tm.texi: Regenerate. + * target.def (output_addr_const_extra): Use + hook_bool_FILEptr_rtx_false. + * targhooks.c (default_asm_output_addr_const_extra): Remove. + * targhooks.h (default_asm_output_addr_const_extra): Remove. + * hooks.c (hook_bool_FILEptr_rtx_false): New functions. + * hooks.h (hook_bool_FILEptr_rtx_false): Declare. + +2011-10-06 David S. Miller <davem@davemloft.net> + + * config/sparc/sparc.md (popcount<mode>2, clz<mode>2): Split up into... + (popcountdi2, popcountsi2, clzdi2, clzsi2): Explicit expanders, in the + SI mode 64-bit code gen case explicitly zero-extend and truncate. + (*popcount<mode>_sp64): Split up into... + (*popcountdi_sp64, *popcountsi_64): Explicit instantiations, and in the + SImode case use truncate. + (*clzsi_sp64): Rewrite to use truncate, and let the expander emit the + subtract so the compiler can optimize it. + (SIDI): Remove unused mode iterator. + +2011-10-06 Bernd Schmidt <bernds@codesourcery.com> + + * function.c (thread_prologue_and_epilogue_insns): Emit split prologue + on the orig_entry_edge. Don't account for it in prologue_clobbered. + +2011-10-06 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/50596 + * tree-vectorizer.h (vect_is_simple_cond): New prototype. + (NUM_PATTERNS): Change to 6. + * tree-vect-patterns.c (vect_recog_mixed_size_cond_pattern): New + function. + (vect_vect_recog_func_ptrs): Add vect_recog_mixed_size_cond_pattern. + (vect_mark_pattern_stmts): Don't create stmt_vinfo for def_stmt + if it already has one, and don't set STMT_VINFO_VECTYPE in it + if it is already set. + * tree-vect-stmts.c (vect_mark_stmts_to_be_vectorized): Handle + COND_EXPR in pattern stmts. + (vect_is_simple_cond): No longer static. + +2001-10-06 Richard Henderson <rth@redhat.com> + + * config/i386/i386.c (ix86_expand_vshuffle): Add AVX2 support. + * config/i386/sse.md (sseshuffint): Remove. + (sseintvecmode): Support V16HI, V8HI, V32QI, V16QI. + (VSHUFFLE_AVX2): New mode iterator. + (vshuffle<mode>): Use it. + (avx_vec_concat<V_256>): Rename from *vec_concat<V_256>_avx. + + * config/i386/i386.c (ix86_expand_sse_movcc): Use correct mode + for vector_all_ones_operand. + (ix86_expand_int_vcond): Distinguish between comparison mode + and data mode. Allow them to differ. + (ix86_expand_vshuffle): Don't force data mode to match maskmode. + +2001-10-06 Richard Henderson <rth@redhat.com> + + * optabs.c (expand_vec_shuffle_expr): Use the proper mode for the + mask operand. Tidy the code. + +2011-10-06 Jakub Jelinek <jakub@redhat.com> + + * tree-vect-patterns.c (vect_pattern_recog_1): Use + vect_recog_func_ptr typedef for the first argument. + (vect_pattern_recog): Rename vect_recog_func_ptr variable + to vect_recog_func, use vect_recog_func_ptr typedef for it. + + PR tree-optimization/49279 + * tree-ssa-structalias.c (find_func_aliases): Don't handle + CAST_RESTRICT. + * tree-ssa-forwprop.c (forward_propagate_addr_expr_1): Allow + restrict propagation. + * tree-ssa.c (useless_type_conversion_p): Don't return false + if TYPE_RESTRICT differs. + +2011-10-06 Bernd Schmidt <bernds@codesourcery.com> + + * function.c (thread_prologue_and_epilogue_insns): Build a vector + of unconverted simple return blocks rather than trying to + recompute them later based on bb_flags bitmap tests. + +2011-10-06 Michael Matz <matz@suse.de> + + * tree-flow.h (get_var_ann): Don't declare. + * tree-flow-inline.h (get_var_ann): Remove. + (set_is_used): Use var_ann, not get_var_ann. + * tree-dfa.c (add_referenced_var): Inline body of get_var_ann. + * tree-profile.c (gimple_gen_edge_profiler): Call + find_referenced_var_in. + (gimple_gen_interval_profiler): Ditto. + (gimple_gen_pow2_profiler): Ditto. + (gimple_gen_one_value_profiler): Ditto. + (gimple_gen_average_profiler): Ditto. + (gimple_gen_ior_profiler): Ditto. + (gimple_gen_ic_profiler): Ditto plus call add_referenced_var. + (gimple_gen_ic_func_profiler): Call add_referenced_var. + * tree-mudflap.c (execute_mudflap_function_ops): Call + add_referenced_var. + +2011-10-06 Jakub Jelinek <jakub@redhat.com> + + * tree-vect-patterns.c (vect_handle_widen_mult_by_const): For lhs + don't set SSA_NAME_DEF_STMT that has been already set by + gimple_build_assign_with_ops. + (vect_recog_pow_pattern, vect_recog_widen_sum_pattern, + vect_operation_fits_smaller_type, vect_recog_over_widening_pattern): + Likewise. + + * tree.h (avoid_folding_inline_builtin): New prototype. + * builtins.c (avoid_folding_inline_builtin): No longer static. + * gimple-fold.c (gimple_fold_builtin): Give up if + avoid_folding_inline_builtin returns true. + +2011-10-06 Richard Guenther <rguenther@suse.de> + + * tree-vect-generic.c (vector_element): Look at previous + generated results. + +2011-10-06 David Edelsohn <dje.gcc@gmail.com> + + PR target/39950 + * config/rs6000/aix.h (TARGET_OS_AIX_CPP_BUILTINS): Define + __powerpc__, __PPC__, __unix__. + +2011-10-06 Michael Matz <matz@suse.de> + + * i386/i386.opt (recip_mask, recip_mask_explicit, + x_recip_mask_explicit): New variables and cl_target member. + (mrecip=): New option. + * i386/i386.h (RECIP_MASK_DIV, RECIP_MASK_SQRT, RECIP_MASK_VEC_DIV, + RECIP_MASK_VEC_SQRT, RECIP_MASK_ALL, RECIP_MASK_NONE): New bitmasks. + (TARGET_RECIP_DIV, TARGET_RECIP_SQRT, TARGET_RECIP_VEC_DIV, + TARGET_RECIP_VEC_SQRT): New tests. + * i386/i386.md (divsf3): Check TARGET_RECIP_DIV. + (sqrt<mode>2): Check TARGET_RECIP_SQRT. + * i386/sse.md (div<mode>3): Check TARGET_RECIP_VEC_DIV. + (sqrt<mode>2): Check TARGET_RECIP_VEC_SQRT. + * i386/i386.c (ix86_option_override_internal): Set recip_mask + for -mrecip and -mrecip=options. + (ix86_function_specific_save): Save recip_mask_explicit. + (ix86_function_specific_restore): Restore recip_mask_explicit. + + * doc/invoke.texi (ix86 Options): Document the new option. + +2011-10-06 Bernd Schmidt <bernds@codesourcery.com> + + PR target/49049 + * config/arm/arm.md (arm_subsi3_insn): Lose the last alternative. + +2011-10-06 Ulrich Weigand <ulrich.weigand@linaro.org> + + PR target/50305 + * config/arm/arm.c (arm_legitimize_reload_address): Recognize + output of a previous pass through legitimize_reload_address. + Do not attempt to optimize addresses if the base register is + equivalent to a constant. + +2011-10-06 Andreas Krebbel <Andreas.Krebbel@de.ibm.com> + + * function.c (thread_prologue_and_epilogue_insns): Mark + last_bb_active as possibly unused. It is unused for targets which + do neither have "return" nor "simple_return" expanders. + +2011-10-06 Richard Guenther <rguenther@suse.de> + + * fold-const.c (fold_ternary_loc): Also fold non-constant + vector CONSTRUCTORs. Make more efficient. + * tree-ssa-dom.c (cprop_operand): Don't handle virtual operands. + (cprop_into_stmt): Don't propagate into virtual operands. + (optimize_stmt): Really dump original statement. + +2011-10-06 Nick Clifton <nickc@redhat.com> + + * config/rx/rx.md (smin3): Revert previous delta. + +2011-10-06 Richard Guenther <rguenther@suse.de> + + PR tree-optimization/38884 + * tree-ssa-sccvn.c (vn_reference_lookup_3): Handle partial + reads from aggregate SSA names. + 2011-10-05 Jakub Jelinek <jakub@redhat.com> * tree-vect-patterns.c (vect_pattern_recog_1): Add stmts_to_replace diff --git a/gcc/ChangeLog.MELT b/gcc/ChangeLog.MELT index 955ffc55002..ebf7bed92e0 100644 --- a/gcc/ChangeLog.MELT +++ b/gcc/ChangeLog.MELT @@ -1,4 +1,8 @@ +2011-10-10 Basile Starynkevitch <basile@starynkevitch.net> + * melt-runtime.h (meltppbuffer, meltppbufsiz): Declare as extern + variables. + 2011-10-08 Basile Starynkevitch <basile@starynkevitch.net> {{Regenerated}} * melt/generated/meltrunsup-inc.c: Regenenate. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index e1232163c9d..cc599b4bdd1 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20111006 +20111010 diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index a7be9a2af55..9e113853f86 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,93 @@ +2011-10-07 Eric Botcazou <ebotcazou@adacore.com> + + PR lto/50492 + * gcc-interface/gigi.h (gnat_pushdecl): Adjust comment. + * gcc-interface/utils.c (global_context): New variable. + (gnat_pushdecl): Initialize it and set it as the DECL_CONTEXT of DECLs + that are either public external or at top level. Use "No" macro. + (end_subprog_body): Call decl_function_context. + (rest_of_subprog_body_compilation): Likewise. + +2011-10-07 Eric Botcazou <ebotcazou@adacore.com> + + * gcc-interface/gigi.h (gnat_useless_type_conversion): Declare. + (rest_of_subprog_body_compilation): Likewise. + * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Variable>: For renaming, + test for useless conversions by means of gnat_useless_type_conversion. + * gcc-interface/trans.c: Include bitmap.h and cgraph.h. + (language_function): Add named_ret_val and other_ret_val. + (f_named_ret_val): New macro. + (f_other_ret_val): Likewise. + (gigi): Call rest_of_subprog_body_compilation. + (struct nrv_data): New structure. + (is_nrv_p): New predicate. + (prune_nrv_r): New helper function. + (prune_nrv_in_block): New function. + (finalize_nrv_r): New helper function. + (finalize_nrv): New function. + (return_value_ok_for_nrv_p): New predicate. + (build_return_expr): If optimization is enabled, record candidates for + the Named Return Value optimization. + (build_function_stub): Call rest_of_subprog_body_compilation. + (Subprogram_Body_to_gnu): If optimization is enabled and there are + candidates, finalize the Named Return Value optimization. + Call rest_of_subprog_body_compilation. + (call_to_gnu): At the end, if a return value is needed, simplify the + result before wrapping it up in a COMPOUND_EXPR. + * gcc-interface/utils.c (end_subprog_body): Split into... + (rest_of_subprog_body_compilation): ...this. New function. + (gnat_useless_type_conversion): Likewise. + +2011-10-06 Thomas Quinot <quinot@adacore.com> + + * einfo.ads, exp_attr.adb, exp_ch3.adb, exp_ch4.adb, exp_ch7.adb, + exp_ch9.adb, exp_ch9.ads, exp_strm.adb, exp_util.adb, freeze.adb, + g-debpoo.ads, opt.ads, par-ch12.adb, par-ch2.adb, par-ch3.adb, + par-ch5.adb, par-ch6.adb, sem_aggr.adb, sem_attr.adb, sem_cat.adb, + sem_ch10.adb, sem_ch12.adb, sem_ch3.adb, sem_ch4.adb, sem_ch5.adb, + sem_ch6.adb, sem_intr.adb, sem_res.ads, sem_type.adb, sem_util.adb, + s-regpat.adb, s-tpopde-vms.ads: Minor reformatting. + * s-osinte-freebsd.ads: Fix for tasking failures on FreeBSD. + +2011-10-06 Ed Schonberg <schonberg@adacore.com> + + * a-cihase.adb, a-ciorma.adb: Avoid accessibility checks in container + references. + +2011-10-06 Matthew Heaney <heaney@adacore.com> + + * a-cuprqu.ads, a-cuprqu.adb, a-cbprqu.ads, a-cbprqu.adb + (Dequeue_Only_High_Priority): Protected procedure now implemented. + +2011-10-06 Vincent Celier <celier@adacore.com> + + * g-trasym.adb: Replace old implementation with the default + implementation that returns list of addresses as "0x...". + * g-trasym.ads: Update the list of platforms with the full + capability. Indicate that there is a default implementation + for other platforms. + * g-trasym-unimplemented.ads, g-trasym-unimplemented.adb: Remove. + * gcc-interface/Makefile.in: Remove g-trasym-unimplemented, as there + is now a default implementation for all platforms without the full + capability. + +2011-10-06 Robert Dewar <dewar@adacore.com> + + * a-ciorse.adb, a-cihase.adb, a-cihase.ads, a-coorse.adb, + a-cborse.adb, a-comutr.adb, a-ciorma.adb, a-cbmutr.adb, + a-cbmutr.ads, a-cbhase.adb, a-cbhase.ads: Minor reformatting and code + reorganization (use conditional expressions). + +2011-10-06 Robert Dewar <dewar@adacore.com> + + * sem_res.adb (Resolve_Arithmetic_Op): Fix bad warning for + floating divide by zero. + +2011-10-06 Ed Schonberg <schonberg@adacore.com> + + * sem_ch6.adb: Limited interfaces that are not immutably limited + are OK in return statements. + 2011-09-30 Iain Sandoe <iains@gcc.gnu.org> * gcc-interface/Makefile.in (Darwin): Partial reversion of previous @@ -8621,15 +8711,16 @@ 2011-08-03 Matthew Heaney <heaney@adacore.com> - * a-cobove.adb (Merge): Move source onto target, instead of using Assign + * a-cobove.adb (Merge): Move source onto target, instead of using + Assign. 2011-08-03 Matthew Heaney <heaney@adacore.com> - * a-cbdlli.adb (Splice): move source items from first to last + * a-cbdlli.adb (Splice): Move source items from first to last. 2011-08-03 Yannick Moy <moy@adacore.com> - * sem_util.ads: comment added. + * sem_util.ads: Add comment. 2011-08-03 Javier Miranda <miranda@adacore.com> diff --git a/gcc/ada/a-cbhase.adb b/gcc/ada/a-cbhase.adb index 7dcd074995d..97a765a6839 100644 --- a/gcc/ada/a-cbhase.adb +++ b/gcc/ada/a-cbhase.adb @@ -47,7 +47,7 @@ package body Ada.Containers.Bounded_Hashed_Sets is overriding function First (Object : Iterator) return Cursor; overriding function Next - (Object : Iterator; + (Object : Iterator; Position : Cursor) return Cursor; ----------------------- @@ -68,9 +68,7 @@ package body Ada.Containers.Bounded_Hashed_Sets is Node : out Count_Type; Inserted : out Boolean); - function Is_In - (HT : Set; - Key : Node_Type) return Boolean; + function Is_In (HT : Set; Key : Node_Type) return Boolean; pragma Inline (Is_In); procedure Set_Element (Node : in out Node_Type; Item : Element_Type); @@ -169,7 +167,6 @@ package body Ada.Containers.Bounded_Hashed_Sets is N : Node_Type renames Source.Nodes (Source_Node); X : Count_Type; B : Boolean; - begin Insert (Target, N.Element, X, B); pragma Assert (B); @@ -233,10 +230,8 @@ package body Ada.Containers.Bounded_Hashed_Sets is begin if Capacity = 0 then C := Source.Length; - elsif Capacity >= Source.Length then C := Capacity; - else raise Capacity_Error with "Capacity value too small"; end if; @@ -396,7 +391,6 @@ package body Ada.Containers.Bounded_Hashed_Sets is N : Node_Type renames Left.Nodes (L_Node); X : Count_Type; B : Boolean; - begin if not Is_In (Right, N) then Insert (Result, N.Element, X, B); -- optimize this ??? @@ -428,7 +422,6 @@ package body Ada.Containers.Bounded_Hashed_Sets is declare S : Set renames Position.Container.all; N : Node_Type renames S.Nodes (Position.Node); - begin return N.Element; end; @@ -488,6 +481,7 @@ package body Ada.Containers.Bounded_Hashed_Sets is function Equivalent_Elements (Left, Right : Cursor) return Boolean is + begin if Left.Node = 0 then raise Constraint_Error with @@ -505,14 +499,15 @@ package body Ada.Containers.Bounded_Hashed_Sets is declare LN : Node_Type renames Left.Container.Nodes (Left.Node); RN : Node_Type renames Right.Container.Nodes (Right.Node); - begin return Equivalent_Elements (LN.Element, RN.Element); end; end Equivalent_Elements; - function Equivalent_Elements (Left : Cursor; Right : Element_Type) - return Boolean is + function Equivalent_Elements + (Left : Cursor; + Right : Element_Type) return Boolean + is begin if Left.Node = 0 then raise Constraint_Error with @@ -528,8 +523,10 @@ package body Ada.Containers.Bounded_Hashed_Sets is end; end Equivalent_Elements; - function Equivalent_Elements (Left : Element_Type; Right : Cursor) - return Boolean is + function Equivalent_Elements + (Left : Element_Type; + Right : Cursor) return Boolean + is begin if Right.Node = 0 then raise Constraint_Error with @@ -551,8 +548,10 @@ package body Ada.Containers.Bounded_Hashed_Sets is -- Equivalent_Keys -- --------------------- - function Equivalent_Keys (Key : Element_Type; Node : Node_Type) - return Boolean is + function Equivalent_Keys + (Key : Element_Type; + Node : Node_Type) return Boolean + is begin return Equivalent_Elements (Key, Node.Element); end Equivalent_Keys; @@ -580,13 +579,9 @@ package body Ada.Containers.Bounded_Hashed_Sets is Item : Element_Type) return Cursor is Node : constant Count_Type := Element_Keys.Find (Container, Item); - begin - if Node = 0 then - return No_Element; - end if; - - return Cursor'(Container'Unrestricted_Access, Node); + return (if Node = 0 then No_Element + else Cursor'(Container'Unrestricted_Access, Node)); end Find; ----------- @@ -595,23 +590,16 @@ package body Ada.Containers.Bounded_Hashed_Sets is function First (Container : Set) return Cursor is Node : constant Count_Type := HT_Ops.First (Container); - begin - if Node = 0 then - return No_Element; - end if; - - return Cursor'(Container'Unrestricted_Access, Node); + return (if Node = 0 then No_Element + else Cursor'(Container'Unrestricted_Access, Node)); end First; overriding function First (Object : Iterator) return Cursor is Node : constant Count_Type := HT_Ops.First (Object.Container.all); begin - if Node = 0 then - return No_Element; - end if; - - return Cursor'(Object.Container, Node); + return (if Node = 0 then No_Element + else Cursor'(Object.Container, Node)); end First; ----------------- @@ -999,11 +987,7 @@ package body Ada.Containers.Bounded_Hashed_Sets is "Position cursor designates wrong set"; end if; - if Position.Node = 0 then - return No_Element; - end if; - - return Next (Position); + return (if Position.Node = 0 then No_Element else Next (Position)); end Next; ------------- @@ -1143,12 +1127,10 @@ package body Ada.Containers.Bounded_Hashed_Sets is (Container : aliased Set; Position : Cursor) return Constant_Reference_Type is + pragma Unreferenced (Container); S : Set renames Position.Container.all; N : Node_Type renames S.Nodes (Position.Node); - begin - pragma Unreferenced (Container); - return (Element => N.Element'Unrestricted_Access); end Constant_Reference; @@ -1316,7 +1298,6 @@ package body Ada.Containers.Bounded_Hashed_Sets is N : Node_Type renames Left.Nodes (L_Node); X : Count_Type; B : Boolean; - begin if not Is_In (Right, N) then Insert (Result, N.Element, X, B); @@ -1344,7 +1325,6 @@ package body Ada.Containers.Bounded_Hashed_Sets is N : Node_Type renames Right.Nodes (R_Node); X : Count_Type; B : Boolean; - begin if not Is_In (Left, N) then Insert (Result, N.Element, X, B); @@ -1367,7 +1347,6 @@ package body Ada.Containers.Bounded_Hashed_Sets is function To_Set (New_Item : Element_Type) return Set is X : Count_Type; B : Boolean; - begin return Result : Set (1, 1) do Insert (Result, New_Item, X, B); @@ -1396,7 +1375,6 @@ package body Ada.Containers.Bounded_Hashed_Sets is N : Node_Type renames Source.Nodes (Src_Node); X : Count_Type; B : Boolean; - begin Insert (Target, N.Element, X, B); end Process; @@ -1413,7 +1391,7 @@ package body Ada.Containers.Bounded_Hashed_Sets is "attempt to tamper with cursors (set is busy)"; end if; - -- ??? + -- ??? why is this code commented out ??? -- declare -- N : constant Count_Type := Target.Length + Source.Length; -- begin @@ -1661,15 +1639,10 @@ package body Ada.Containers.Bounded_Hashed_Sets is (Container : Set; Key : Key_Type) return Cursor is - Node : constant Count_Type := - Key_Keys.Find (Container, Key); - + Node : constant Count_Type := Key_Keys.Find (Container, Key); begin - if Node = 0 then - return No_Element; - end if; - - return Cursor'(Container'Unrestricted_Access, Node); + return (if Node = 0 then No_Element + else Cursor'(Container'Unrestricted_Access, Node)); end Find; --------- @@ -1684,7 +1657,6 @@ package body Ada.Containers.Bounded_Hashed_Sets is end if; pragma Assert (Vet (Position), "bad cursor in function Key"); - return Key (Position.Container.Nodes (Position.Node).Element); end Key; @@ -1697,8 +1669,7 @@ package body Ada.Containers.Bounded_Hashed_Sets is Key : Key_Type; New_Item : Element_Type) is - Node : constant Count_Type := - Key_Keys.Find (Container, Key); + Node : constant Count_Type := Key_Keys.Find (Container, Key); begin if Node = 0 then @@ -1733,7 +1704,7 @@ package body Ada.Containers.Bounded_Hashed_Sets is "Position cursor designates wrong set"; end if; - -- ??? + -- ??? why is this code commented out ??? -- if HT.Buckets = null -- or else HT.Buckets'Length = 0 -- or else HT.Length = 0 @@ -1747,7 +1718,8 @@ package body Ada.Containers.Bounded_Hashed_Sets is (Vet (Position), "bad cursor in Update_Element_Preserving_Key"); - -- Record bucket now, in case key is changed. + -- Record bucket now, in case key is changed + Indx := HT_Ops.Index (Container.Buckets, N (Position.Node)); declare @@ -1823,10 +1795,10 @@ package body Ada.Containers.Bounded_Hashed_Sets is function Reference_Preserving_Key (Container : aliased in out Set; - Key : Key_Type) return Reference_Type + Key : Key_Type) return Reference_Type is Position : constant Cursor := Find (Container, Key); - N : Node_Type renames Container.Nodes (Position.Node); + N : Node_Type renames Container.Nodes (Position.Node); begin return (Element => N.Element'Unrestricted_Access); end Reference_Preserving_Key; diff --git a/gcc/ada/a-cbhase.ads b/gcc/ada/a-cbhase.ads index c72b8ab8597..3f6b6696871 100644 --- a/gcc/ada/a-cbhase.ads +++ b/gcc/ada/a-cbhase.ads @@ -148,8 +148,7 @@ package Ada.Containers.Bounded_Hashed_Sets is function Constant_Reference (Container : aliased Set; - Position : Cursor) - return Constant_Reference_Type; + Position : Cursor) return Constant_Reference_Type; procedure Assign (Target : in out Set; Source : Set); -- If Target denotes the same object as Source, then the operation has no @@ -355,8 +354,9 @@ package Ada.Containers.Bounded_Hashed_Sets is Process : not null access procedure (Position : Cursor)); -- Calls Process for each node in the set - function Iterate (Container : Set) - return Set_Iterator_Interfaces.Forward_Iterator'Class; + function Iterate + (Container : Set) + return Set_Iterator_Interfaces.Forward_Iterator'Class; generic type Key_Type (<>) is private; @@ -431,13 +431,11 @@ package Ada.Containers.Bounded_Hashed_Sets is function Reference_Preserving_Key (Container : aliased in out Set; - Position : Cursor) - return Reference_Type; + Position : Cursor) return Reference_Type; function Reference_Preserving_Key (Container : aliased in out Set; - Key : Key_Type) - return Reference_Type; + Key : Key_Type) return Reference_Type; private type Reference_Type (Element : not null access Element_Type) @@ -446,7 +444,6 @@ package Ada.Containers.Bounded_Hashed_Sets is end Generic_Keys; private - pragma Inline (Next); type Node_Type is record @@ -519,6 +516,6 @@ private for Constant_Reference_Type'Write use Write; Empty_Set : constant Set := - (Hash_Table_Type with Capacity => 0, Modulus => 0); + (Hash_Table_Type with Capacity => 0, Modulus => 0); end Ada.Containers.Bounded_Hashed_Sets; diff --git a/gcc/ada/a-cbmutr.adb b/gcc/ada/a-cbmutr.adb index f4bdc5e4035..7ad2de4e62a 100644 --- a/gcc/ada/a-cbmutr.adb +++ b/gcc/ada/a-cbmutr.adb @@ -54,11 +54,11 @@ package body Ada.Containers.Bounded_Multiway_Trees is overriding function First (Object : Child_Iterator) return Cursor; overriding function Next - (Object : Child_Iterator; + (Object : Child_Iterator; Position : Cursor) return Cursor; overriding function Previous - (Object : Child_Iterator; + (Object : Child_Iterator; Position : Cursor) return Cursor; overriding function Last (Object : Child_Iterator) return Cursor; @@ -599,10 +599,8 @@ package body Ada.Containers.Bounded_Multiway_Trees is begin if Capacity = 0 then C := Source.Count; - elsif Capacity >= Source.Count then C := Capacity; - else raise Capacity_Error with "Capacity value too small"; end if; @@ -841,12 +839,12 @@ package body Ada.Containers.Bounded_Multiway_Trees is -- nodes that contain elements that have been inserted onto the tree, -- and another for the "inactive" nodes of the free store, from which -- nodes are allocated when a new child is inserted in the tree. - -- + -- We desire that merely declaring a tree object should have only -- minimal cost; specially, we want to avoid having to initialize the -- free store (to fill in the links), especially if the capacity of the -- tree object is large. - -- + -- The head of the free list is indicated by Container.Free. If its -- value is non-negative, then the free store has been initialized in -- the "normal" way: Container.Free points to the head of the list of @@ -854,20 +852,20 @@ package body Ada.Containers.Bounded_Multiway_Trees is -- empty. Each node on the free list has been initialized to point to -- the next free node (via its Next component), and the value 0 means -- that this is the last node of the free list. - -- + -- If Container.Free is negative, then the links on the free store have -- not been initialized. In this case the link values are implied: the -- free store comprises the components of the node array started with -- the absolute value of Container.Free, and continuing until the end of -- the array (Nodes'Last). - -- + -- We prefer to lazy-init the free store (in fact, we would prefer to -- not initialize it at all, because such initialization is an O(n) -- operation). The time when we need to actually initialize the nodes in -- the free store is when the node that becomes inactive is not at the -- end of the active list. The free store would then be discontigous and -- so its nodes would need to be linked in the traditional way. - -- + -- It might be possible to perform an optimization here. Suppose that -- the free store can be represented as having two parts: one comprising -- the non-contiguous inactive nodes linked together in the normal way, @@ -1218,8 +1216,8 @@ package body Ada.Containers.Bounded_Multiway_Trees is Right_Subtree : Count_Type) return Boolean is begin - if Left_Tree.Elements (Left_Subtree) - /= Right_Tree.Elements (Right_Subtree) + if Left_Tree.Elements (Left_Subtree) /= + Right_Tree.Elements (Right_Subtree) then return False; end if; @@ -1262,7 +1260,6 @@ package body Ada.Containers.Bounded_Multiway_Trees is function First (Object : Child_Iterator) return Cursor is Node : Count_Type'Base; - begin Node := Object.Container.Nodes (Object.Position.Node).Children.First; return (Object.Container, Node); @@ -1722,11 +1719,9 @@ package body Ada.Containers.Bounded_Multiway_Trees is function Is_Root (Position : Cursor) return Boolean is begin - if Position.Container = null then - return False; - end if; - - return Position.Node = Root_Node (Position.Container.all); + return + (if Position.Container = null then False + else Position.Node = Root_Node (Position.Container.all)); end Is_Root; ------------- @@ -1839,7 +1834,7 @@ package body Ada.Containers.Bounded_Multiway_Trees is function Iterate_Children (Container : Tree; Parent : Cursor) - return Tree_Iterator_Interfaces.Reversible_Iterator'Class + return Tree_Iterator_Interfaces.Reversible_Iterator'Class is pragma Unreferenced (Container); begin @@ -2039,10 +2034,9 @@ package body Ada.Containers.Bounded_Multiway_Trees is end Next; function Next - (Object : Child_Iterator; + (Object : Child_Iterator; Position : Cursor) return Cursor is - begin if Object.Container /= Position.Container then raise Program_Error; @@ -2201,7 +2195,7 @@ package body Ada.Containers.Bounded_Multiway_Trees is -------------- overriding function Previous - (Object : Child_Iterator; + (Object : Child_Iterator; Position : Cursor) return Cursor is begin diff --git a/gcc/ada/a-cbmutr.ads b/gcc/ada/a-cbmutr.ads index e014f82d453..797b6ea6214 100644 --- a/gcc/ada/a-cbmutr.ads +++ b/gcc/ada/a-cbmutr.ads @@ -182,7 +182,7 @@ package Ada.Containers.Bounded_Multiway_Trees is function Iterate_Children (Container : Tree; Parent : Cursor) - return Tree_Iterator_Interfaces.Reversible_Iterator'Class; + return Tree_Iterator_Interfaces.Reversible_Iterator'Class; function Child_Count (Parent : Cursor) return Count_Type; diff --git a/gcc/ada/a-cborse.adb b/gcc/ada/a-cborse.adb index 1974c6cccef..674d2abee33 100644 --- a/gcc/ada/a-cborse.adb +++ b/gcc/ada/a-cborse.adb @@ -326,7 +326,6 @@ package body Ada.Containers.Bounded_Ordered_Sets is function New_Node return Count_Type is Result : Count_Type; - begin Allocate (Target, Result); return Result; @@ -376,13 +375,9 @@ package body Ada.Containers.Bounded_Ordered_Sets is function Ceiling (Container : Set; Item : Element_Type) return Cursor is Node : constant Count_Type := Element_Keys.Ceiling (Container, Item); - begin - if Node = 0 then - return No_Element; - end if; - - return Cursor'(Container'Unrestricted_Access, Node); + return (if Node = 0 then No_Element + else Cursor'(Container'Unrestricted_Access, Node)); end Ceiling; ----------- @@ -425,10 +420,8 @@ package body Ada.Containers.Bounded_Ordered_Sets is begin if Capacity = 0 then C := Source.Length; - elsif Capacity >= Source.Length then C := Capacity; - else raise Capacity_Error with "Capacity value too small"; end if; @@ -479,7 +472,6 @@ package body Ada.Containers.Bounded_Ordered_Sets is procedure Delete_First (Container : in out Set) is X : constant Count_Type := Container.First; - begin if X /= 0 then Tree_Operations.Delete_Node_Sans_Free (Container, X); @@ -493,7 +485,6 @@ package body Ada.Containers.Bounded_Ordered_Sets is procedure Delete_Last (Container : in out Set) is X : constant Count_Type := Container.Last; - begin if X /= 0 then Tree_Operations.Delete_Node_Sans_Free (Container, X); @@ -533,13 +524,7 @@ package body Ada.Containers.Bounded_Ordered_Sets is function Equivalent_Elements (Left, Right : Element_Type) return Boolean is begin - if Left < Right - or else Right < Left - then - return False; - else - return True; - end if; + return (if Left < Right or else Right < Left then False else True); end Equivalent_Elements; --------------------- @@ -559,13 +544,9 @@ package body Ada.Containers.Bounded_Ordered_Sets is function Is_Equivalent_Node_Node (L, R : Node_Type) return Boolean is begin - if L.Element < R.Element then - return False; - elsif R.Element < L.Element then - return False; - else - return True; - end if; + return (if L.Element < R.Element then False + elsif R.Element < L.Element then False + else True); end Is_Equivalent_Node_Node; -- Start of processing for Equivalent_Sets @@ -580,7 +561,6 @@ package body Ada.Containers.Bounded_Ordered_Sets is procedure Exclude (Container : in out Set; Item : Element_Type) is X : constant Count_Type := Element_Keys.Find (Container, Item); - begin if X /= 0 then Tree_Operations.Delete_Node_Sans_Free (Container, X); @@ -594,13 +574,9 @@ package body Ada.Containers.Bounded_Ordered_Sets is function Find (Container : Set; Item : Element_Type) return Cursor is Node : constant Count_Type := Element_Keys.Find (Container, Item); - begin - if Node = 0 then - return No_Element; - end if; - - return Cursor'(Container'Unrestricted_Access, Node); + return (if Node = 0 then No_Element + else Cursor'(Container'Unrestricted_Access, Node)); end Find; ----------- @@ -609,23 +585,15 @@ package body Ada.Containers.Bounded_Ordered_Sets is function First (Container : Set) return Cursor is begin - if Container.First = 0 then - return No_Element; - end if; - - return Cursor'(Container'Unrestricted_Access, Container.First); + return (if Container.First = 0 then No_Element + else Cursor'(Container'Unrestricted_Access, Container.First)); end First; function First (Object : Iterator) return Cursor is begin - if Object.Container.First = 0 then - return No_Element; - else - return - Cursor'( - Object.Container.all'Unrestricted_Access, - Object.Container.First); - end if; + return (if Object.Container.First = 0 then No_Element + else Cursor'(Object.Container.all'Unrestricted_Access, + Object.Container.First)); end First; ------------------- @@ -647,13 +615,9 @@ package body Ada.Containers.Bounded_Ordered_Sets is function Floor (Container : Set; Item : Element_Type) return Cursor is Node : constant Count_Type := Element_Keys.Floor (Container, Item); - begin - if Node = 0 then - return No_Element; - end if; - - return Cursor'(Container'Unrestricted_Access, Node); + return (if Node = 0 then No_Element + else Cursor'(Container'Unrestricted_Access, Node)); end Floor; ------------------ @@ -694,13 +658,9 @@ package body Ada.Containers.Bounded_Ordered_Sets is function Ceiling (Container : Set; Key : Key_Type) return Cursor is Node : constant Count_Type := Key_Keys.Ceiling (Container, Key); - begin - if Node = 0 then - return No_Element; - end if; - - return Cursor'(Container'Unrestricted_Access, Node); + return (if Node = 0 then No_Element + else Cursor'(Container'Unrestricted_Access, Node)); end Ceiling; -------------- @@ -749,13 +709,7 @@ package body Ada.Containers.Bounded_Ordered_Sets is function Equivalent_Keys (Left, Right : Key_Type) return Boolean is begin - if Left < Right - or else Right < Left - then - return False; - else - return True; - end if; + return (if Left < Right or else Right < Left then False else True); end Equivalent_Keys; ------------- @@ -764,7 +718,6 @@ package body Ada.Containers.Bounded_Ordered_Sets is procedure Exclude (Container : in out Set; Key : Key_Type) is X : constant Count_Type := Key_Keys.Find (Container, Key); - begin if X /= 0 then Tree_Operations.Delete_Node_Sans_Free (Container, X); @@ -778,13 +731,9 @@ package body Ada.Containers.Bounded_Ordered_Sets is function Find (Container : Set; Key : Key_Type) return Cursor is Node : constant Count_Type := Key_Keys.Find (Container, Key); - begin - if Node = 0 then - return No_Element; - end if; - - return Cursor'(Container'Unrestricted_Access, Node); + return (if Node = 0 then No_Element + else Cursor'(Container'Unrestricted_Access, Node)); end Find; ----------- @@ -793,13 +742,9 @@ package body Ada.Containers.Bounded_Ordered_Sets is function Floor (Container : Set; Key : Key_Type) return Cursor is Node : constant Count_Type := Key_Keys.Floor (Container, Key); - begin - if Node = 0 then - return No_Element; - end if; - - return Cursor'(Container'Unrestricted_Access, Node); + return (if Node = 0 then No_Element + else Cursor'(Container'Unrestricted_Access, Node)); end Floor; ------------------------- @@ -1069,7 +1014,6 @@ package body Ada.Containers.Bounded_Ordered_Sets is function New_Node return Count_Type is Result : Count_Type; - begin Allocate (Container, Result); return Result; @@ -1133,7 +1077,6 @@ package body Ada.Containers.Bounded_Ordered_Sets is function New_Node return Count_Type is Result : Count_Type; - begin Allocate (Dst_Set, Result); return Result; @@ -1287,22 +1230,15 @@ package body Ada.Containers.Bounded_Ordered_Sets is function Last (Container : Set) return Cursor is begin - if Container.Last = 0 then - return No_Element; - end if; - - return Cursor'(Container'Unrestricted_Access, Container.Last); + return (if Container.Last = 0 then No_Element + else Cursor'(Container'Unrestricted_Access, Container.Last)); end Last; function Last (Object : Iterator) return Cursor is begin - if Object.Container.Last = 0 then - return No_Element; - else - return Cursor'( - Object.Container.all'Unrestricted_Access, - Object.Container.Last); - end if; + return (if Object.Container.Last = 0 then No_Element + else Cursor'(Object.Container.all'Unrestricted_Access, + Object.Container.Last)); end Last; ------------------ @@ -1388,7 +1324,6 @@ package body Ada.Containers.Bounded_Ordered_Sets is function Next (Object : Iterator; Position : Cursor) return Cursor is pragma Unreferenced (Object); - begin return Next (Position); end Next; @@ -1427,13 +1362,9 @@ package body Ada.Containers.Bounded_Ordered_Sets is Tree_Operations.Previous (Position.Container.all, Position.Node); - begin - if Node = 0 then - return No_Element; - end if; - - return Cursor'(Position.Container, Node); + return (if Node = 0 then No_Element + else Cursor'(Position.Container, Node)); end; end Previous; @@ -1466,7 +1397,6 @@ package body Ada.Containers.Bounded_Ordered_Sets is declare S : Set renames Position.Container.all; - B : Natural renames S.Busy; L : Natural renames S.Lock; @@ -1608,11 +1538,10 @@ package body Ada.Containers.Bounded_Ordered_Sets is function New_Node return Count_Type is begin Node.Element := Item; - Node.Color := Red_Black_Trees.Red; - Node.Parent := 0; - Node.Right := 0; - Node.Left := 0; - + Node.Color := Red_Black_Trees.Red; + Node.Parent := 0; + Node.Right := 0; + Node.Left := 0; return Index; end New_Node; diff --git a/gcc/ada/a-cbprqu.adb b/gcc/ada/a-cbprqu.adb index 09a06b277ad..e5aff11b36e 100644 --- a/gcc/ada/a-cbprqu.adb +++ b/gcc/ada/a-cbprqu.adb @@ -44,6 +44,24 @@ package body Ada.Containers.Bounded_Priority_Queues is List.Container.Delete_First; end Dequeue; + procedure Dequeue + (List : in out List_Type; + At_Least : Queue_Priority; + Element : in out Queue_Interfaces.Element_Type; + Success : out Boolean) + is + begin + if List.Length = 0 + or else not Before (At_Least, Get_Priority (List.First_Element)) + then + Success := False; + return; + end if; + + List.Dequeue (Element); + Success := True; + end Dequeue; + ------------- -- Enqueue -- ------------- @@ -83,6 +101,18 @@ package body Ada.Containers.Bounded_Priority_Queues is end if; end Enqueue; + ------------------- + -- First_Element -- + ------------------- + + function First_Element + (List : List_Type) return Queue_Interfaces.Element_Type + is + begin + -- Use Constant_Reference for this. ??? + return List.Container.First_Element; + end First_Element; + ------------ -- Length -- ------------ @@ -125,14 +155,18 @@ package body Ada.Containers.Bounded_Priority_Queues is List.Dequeue (Element); end Dequeue; - -- ??? - -- entry Dequeue_Only_High_Priority - -- (Low_Priority : Queue_Priority; - -- Element : out Queue_Interfaces.Element_Type) when True - -- is - -- begin - -- null; - -- end Dequeue_Only_High_Priority; + -------------------------------- + -- Dequeue_Only_High_Priority -- + -------------------------------- + + procedure Dequeue_Only_High_Priority + (At_Least : Queue_Priority; + Element : in out Queue_Interfaces.Element_Type; + Success : out Boolean) + is + begin + List.Dequeue (At_Least, Element, Success); + end Dequeue_Only_High_Priority; -------------- -- Enqueue -- diff --git a/gcc/ada/a-cbprqu.ads b/gcc/ada/a-cbprqu.ads index 589ee313894..0d0f1689191 100644 --- a/gcc/ada/a-cbprqu.ads +++ b/gcc/ada/a-cbprqu.ads @@ -70,6 +70,15 @@ package Ada.Containers.Bounded_Priority_Queues is (List : in out List_Type; Element : out Queue_Interfaces.Element_Type); + procedure Dequeue + (List : in out List_Type; + At_Least : Queue_Priority; + Element : in out Queue_Interfaces.Element_Type; + Success : out Boolean); + + function First_Element + (List : List_Type) return Queue_Interfaces.Element_Type; + function Length (List : List_Type) return Count_Type; function Max_Length (List : List_Type) return Count_Type; @@ -102,11 +111,18 @@ package Ada.Containers.Bounded_Priority_Queues is overriding entry Dequeue (Element : out Queue_Interfaces.Element_Type); - -- ??? - -- not overriding - -- entry Dequeue_Only_High_Priority - -- (Low_Priority : Queue_Priority; - -- Element : out Queue_Interfaces.Element_Type); + -- The priority queue operation Dequeue_Only_High_Priority had been a + -- protected entry in early drafts of AI05-0159, but it was discovered + -- that that operation as specified was not in fact implementable. The + -- operation was changed from an entry to a protected procedure per the + -- ARG meeting in Edinburgh (June 2011), with a different signature and + -- semantics. + + not overriding + procedure Dequeue_Only_High_Priority + (At_Least : Queue_Priority; + Element : in out Queue_Interfaces.Element_Type; + Success : out Boolean); overriding function Current_Use return Count_Type; @@ -115,6 +131,7 @@ package Ada.Containers.Bounded_Priority_Queues is function Peak_Use return Count_Type; private + List : Implementation.List_Type (Capacity); end Queue; diff --git a/gcc/ada/a-cihase.adb b/gcc/ada/a-cihase.adb index dd43229b5e2..e52f38bba9f 100644 --- a/gcc/ada/a-cihase.adb +++ b/gcc/ada/a-cihase.adb @@ -49,7 +49,7 @@ package body Ada.Containers.Indefinite_Hashed_Sets is overriding function First (Object : Iterator) return Cursor; overriding function Next - (Object : Iterator; + (Object : Iterator; Position : Cursor) return Cursor; ----------------------- @@ -426,8 +426,7 @@ package body Ada.Containers.Indefinite_Hashed_Sets is -- Equivalent_Elements -- ------------------------- - function Equivalent_Elements (Left, Right : Cursor) - return Boolean is + function Equivalent_Elements (Left, Right : Cursor) return Boolean is begin if Left.Node = null then raise Constraint_Error with @@ -457,8 +456,10 @@ package body Ada.Containers.Indefinite_Hashed_Sets is Right.Node.Element.all); end Equivalent_Elements; - function Equivalent_Elements (Left : Cursor; Right : Element_Type) - return Boolean is + function Equivalent_Elements + (Left : Cursor; + Right : Element_Type) return Boolean + is begin if Left.Node = null then raise Constraint_Error with @@ -475,8 +476,10 @@ package body Ada.Containers.Indefinite_Hashed_Sets is return Equivalent_Elements (Left.Node.Element.all, Right); end Equivalent_Elements; - function Equivalent_Elements (Left : Element_Type; Right : Cursor) - return Boolean is + function Equivalent_Elements + (Left : Element_Type; + Right : Cursor) return Boolean + is begin if Right.Node = null then raise Constraint_Error with @@ -497,8 +500,10 @@ package body Ada.Containers.Indefinite_Hashed_Sets is -- Equivalent_Keys -- --------------------- - function Equivalent_Keys (Key : Element_Type; Node : Node_Access) - return Boolean is + function Equivalent_Keys + (Key : Element_Type; + Node : Node_Access) return Boolean + is begin return Equivalent_Elements (Key, Node.Element.all); end Equivalent_Keys; @@ -535,13 +540,9 @@ package body Ada.Containers.Indefinite_Hashed_Sets is Item : Element_Type) return Cursor is Node : constant Node_Access := Element_Keys.Find (Container.HT, Item); - begin - if Node = null then - return No_Element; - end if; - - return Cursor'(Container'Unrestricted_Access, Node); + return (if Node = null then No_Element + else Cursor'(Container'Unrestricted_Access, Node)); end Find; -------------------- @@ -604,23 +605,16 @@ package body Ada.Containers.Indefinite_Hashed_Sets is function First (Container : Set) return Cursor is Node : constant Node_Access := HT_Ops.First (Container.HT); - begin - if Node = null then - return No_Element; - end if; - - return Cursor'(Container'Unrestricted_Access, Node); + return (if Node = null then No_Element + else Cursor'(Container'Unrestricted_Access, Node)); end First; function First (Object : Iterator) return Cursor is Node : constant Node_Access := HT_Ops.First (Object.Container.HT); begin - if Node = null then - return No_Element; - end if; - - return Cursor'(Object.Container, Node); + return (if Node = null then No_Element + else Cursor'(Object.Container, Node)); end First; ---------- @@ -750,7 +744,6 @@ package body Ada.Containers.Indefinite_Hashed_Sets is function New_Node (Next : Node_Access) return Node_Access is Element : Element_Access := new Element_Type'(New_Item); - begin return new Node_Type'(Element, Next); exception @@ -1025,13 +1018,9 @@ package body Ada.Containers.Indefinite_Hashed_Sets is declare HT : Hash_Table_Type renames Position.Container.HT; Node : constant Node_Access := HT_Ops.Next (HT, Position.Node); - begin - if Node = null then - return No_Element; - end if; - - return Cursor'(Position.Container, Node); + return (if Node = null then No_Element + else Cursor'(Position.Container, Node)); end; end Next; @@ -1041,7 +1030,7 @@ package body Ada.Containers.Indefinite_Hashed_Sets is end Next; function Next - (Object : Iterator; + (Object : Iterator; Position : Cursor) return Cursor is begin @@ -1050,11 +1039,7 @@ package body Ada.Containers.Indefinite_Hashed_Sets is "Position cursor designates wrong set"; end if; - if Position.Node = null then - return No_Element; - end if; - - return Next (Position); + return (if Position.Node = null then No_Element else Next (Position)); end Next; ------------- @@ -1166,7 +1151,6 @@ package body Ada.Containers.Indefinite_Hashed_Sets is (Stream : not null access Root_Stream_Type'Class) return Node_Access is X : Element_Access := new Element_Type'(Element_Type'Input (Stream)); - begin return new Node_Type'(X, null); exception @@ -1183,10 +1167,9 @@ package body Ada.Containers.Indefinite_Hashed_Sets is (Container : aliased Set; Position : Cursor) return Constant_Reference_Type is - begin pragma Unreferenced (Container); - - return (Element => Position.Node.Element); + begin + return (Element => Position.Node.Element.all'Access); end Constant_Reference; ------------- @@ -1301,8 +1284,7 @@ package body Ada.Containers.Indefinite_Hashed_Sets is Iterate_Source_When_Empty_Target : declare procedure Process (Src_Node : Node_Access); - procedure Iterate is - new HT_Ops.Generic_Iteration (Process); + procedure Iterate is new HT_Ops.Generic_Iteration (Process); ------------- -- Process -- @@ -1535,12 +1517,10 @@ package body Ada.Containers.Indefinite_Hashed_Sets is ------------ function To_Set (New_Item : Element_Type) return Set is - HT : Hash_Table_Type; - + HT : Hash_Table_Type; Node : Node_Access; Inserted : Boolean; pragma Unreferenced (Node, Inserted); - begin Insert (HT, New_Item, Node, Inserted); return Set'(Controlled with HT); @@ -1578,7 +1558,6 @@ package body Ada.Containers.Indefinite_Hashed_Sets is function New_Node (Next : Node_Access) return Node_Access is Tgt : Element_Access := new Element_Type'(Src); - begin return new Node_Type'(Tgt, Next); exception @@ -1655,14 +1634,10 @@ package body Ada.Containers.Indefinite_Hashed_Sets is ------------- procedure Process (L_Node : Node_Access) is - Src : Element_Type renames L_Node.Element.all; - - J : constant Hash_Type := Hash (Src) mod Buckets'Length; - + Src : Element_Type renames L_Node.Element.all; + J : constant Hash_Type := Hash (Src) mod Buckets'Length; Bucket : Node_Access renames Buckets (J); - - Tgt : Element_Access := new Element_Type'(Src); - + Tgt : Element_Access := new Element_Type'(Src); begin Bucket := new Node_Type'(Tgt, Bucket); exception @@ -1940,13 +1915,9 @@ package body Ada.Containers.Indefinite_Hashed_Sets is Key : Key_Type) return Cursor is Node : constant Node_Access := Key_Keys.Find (Container.HT, Key); - begin - if Node = null then - return No_Element; - end if; - - return Cursor'(Container'Unrestricted_Access, Node); + return (if Node = null then No_Element + else Cursor'(Container'Unrestricted_Access, Node)); end Find; --------- @@ -2101,16 +2072,16 @@ package body Ada.Containers.Indefinite_Hashed_Sets is is pragma Unreferenced (Container); begin - return (Element => Position.Node.Element); + return (Element => Position.Node.Element.all'Access); end Reference_Preserving_Key; function Reference_Preserving_Key (Container : aliased in out Set; - Key : Key_Type) return Reference_Type + Key : Key_Type) return Reference_Type is Position : constant Cursor := Find (Container, Key); begin - return (Element => Position.Node.Element); + return (Element => Position.Node.Element.all'Access); end Reference_Preserving_Key; end Generic_Keys; diff --git a/gcc/ada/a-cihase.ads b/gcc/ada/a-cihase.ads index b055c1be153..860034469ea 100644 --- a/gcc/ada/a-cihase.ads +++ b/gcc/ada/a-cihase.ads @@ -414,13 +414,11 @@ package Ada.Containers.Indefinite_Hashed_Sets is function Reference_Preserving_Key (Container : aliased in out Set; - Position : Cursor) - return Reference_Type; + Position : Cursor) return Reference_Type; function Reference_Preserving_Key (Container : aliased in out Set; - Key : Key_Type) - return Reference_Type; + Key : Key_Type) return Reference_Type; private type Reference_Type (Element : not null access Element_Type) @@ -428,7 +426,6 @@ package Ada.Containers.Indefinite_Hashed_Sets is end Generic_Keys; private - pragma Inline (Next); type Node_Type; diff --git a/gcc/ada/a-ciorma.adb b/gcc/ada/a-ciorma.adb index c30abd08046..0947654a64c 100644 --- a/gcc/ada/a-ciorma.adb +++ b/gcc/ada/a-ciorma.adb @@ -36,6 +36,7 @@ with Ada.Containers.Red_Black_Trees.Generic_Keys; pragma Elaborate_All (Ada.Containers.Red_Black_Trees.Generic_Keys); package body Ada.Containers.Indefinite_Ordered_Maps is + pragma Suppress (All_Checks); type Iterator is new Map_Iterator_Interfaces.Reversible_Iterator with record @@ -279,8 +280,7 @@ package body Ada.Containers.Indefinite_Ordered_Maps is -- Adjust -- ------------ - procedure Adjust is - new Tree_Operations.Generic_Adjust (Copy_Tree); + procedure Adjust is new Tree_Operations.Generic_Adjust (Copy_Tree); procedure Adjust (Container : in out Map) is begin @@ -293,21 +293,16 @@ package body Ada.Containers.Indefinite_Ordered_Maps is function Ceiling (Container : Map; Key : Key_Type) return Cursor is Node : constant Node_Access := Key_Ops.Ceiling (Container.Tree, Key); - begin - if Node = null then - return No_Element; - end if; - - return Cursor'(Container'Unrestricted_Access, Node); + return (if Node = null then No_Element + else Cursor'(Container'Unrestricted_Access, Node)); end Ceiling; ----------- -- Clear -- ----------- - procedure Clear is - new Tree_Operations.Generic_Clear (Delete_Tree); + procedure Clear is new Tree_Operations.Generic_Clear (Delete_Tree); procedure Clear (Container : in out Map) is begin @@ -331,7 +326,9 @@ package body Ada.Containers.Indefinite_Ordered_Maps is (Container : Map; Key : Key_Type) return Constant_Reference_Type is - begin return (Element => Container.Element (Key)'Unrestricted_Access); + Node : aliased Element_Type := Element (Container, Key); + begin + return (Element => Node'Access); end Constant_Reference; -------------- @@ -350,6 +347,7 @@ package body Ada.Containers.Indefinite_Ordered_Maps is function Copy_Node (Source : Node_Access) return Node_Access is K : Key_Access := new Key_Type'(Source.Key.all); E : Element_Access; + begin E := new Element_Type'(Source.Element.all); @@ -418,7 +416,6 @@ package body Ada.Containers.Indefinite_Ordered_Maps is procedure Delete_First (Container : in out Map) is X : Node_Access := Container.Tree.First; - begin if X /= null then Tree_Operations.Delete_Node_Sans_Free (Container.Tree, X); @@ -432,7 +429,6 @@ package body Ada.Containers.Indefinite_Ordered_Maps is procedure Delete_Last (Container : in out Map) is X : Node_Access := Container.Tree.Last; - begin if X /= null then Tree_Operations.Delete_Node_Sans_Free (Container.Tree, X); @@ -479,13 +475,7 @@ package body Ada.Containers.Indefinite_Ordered_Maps is function Equivalent_Keys (Left, Right : Key_Type) return Boolean is begin - if Left < Right - or else Right < Left - then - return False; - else - return True; - end if; + return (if Left < Right or else Right < Left then False else True); end Equivalent_Keys; ------------- @@ -494,7 +484,6 @@ package body Ada.Containers.Indefinite_Ordered_Maps is procedure Exclude (Container : in out Map; Key : Key_Type) is X : Node_Access := Key_Ops.Find (Container.Tree, Key); - begin if X /= null then Tree_Operations.Delete_Node_Sans_Free (Container.Tree, X); @@ -508,13 +497,9 @@ package body Ada.Containers.Indefinite_Ordered_Maps is function Find (Container : Map; Key : Key_Type) return Cursor is Node : constant Node_Access := Key_Ops.Find (Container.Tree, Key); - begin - if Node = null then - return No_Element; - end if; - - return Cursor'(Container'Unrestricted_Access, Node); + return (if Node = null then No_Element + else Cursor'(Container'Unrestricted_Access, Node)); end Find; ----------- @@ -523,25 +508,17 @@ package body Ada.Containers.Indefinite_Ordered_Maps is function First (Container : Map) return Cursor is T : Tree_Type renames Container.Tree; - begin - if T.First = null then - return No_Element; - end if; - - return Cursor'(Container'Unrestricted_Access, T.First); + return (if T.First = null then No_Element + else Cursor'(Container'Unrestricted_Access, T.First)); end First; function First (Object : Iterator) return Cursor is M : constant Map_Access := Object.Container; N : constant Node_Access := M.Tree.First; - begin - if N = null then - return No_Element; - else - return Cursor'(Object.Container.all'Unchecked_Access, N); - end if; + return (if N = null then No_Element + else Cursor'(Object.Container.all'Unchecked_Access, N)); end First; ------------------- @@ -580,13 +557,9 @@ package body Ada.Containers.Indefinite_Ordered_Maps is function Floor (Container : Map; Key : Key_Type) return Cursor is Node : constant Node_Access := Key_Ops.Floor (Container.Tree, Key); - begin - if Node = null then - return No_Element; - end if; - - return Cursor'(Container'Unrestricted_Access, Node); + return (if Node = null then No_Element + else Cursor'(Container'Unrestricted_Access, Node)); end Floor; ---------- @@ -608,6 +581,7 @@ package body Ada.Containers.Indefinite_Ordered_Maps is begin Free_Key (X.Key); + exception when others => X.Key := null; @@ -625,6 +599,7 @@ package body Ada.Containers.Indefinite_Ordered_Maps is begin Free_Element (X.Element); + exception when others => X.Element := null; @@ -771,18 +746,11 @@ package body Ada.Containers.Indefinite_Ordered_Maps is -- Is_Equal_Node_Node -- ------------------------ - function Is_Equal_Node_Node - (L, R : Node_Access) return Boolean is + function Is_Equal_Node_Node (L, R : Node_Access) return Boolean is begin - if L.Key.all < R.Key.all then - return False; - - elsif R.Key.all < L.Key.all then - return False; - - else - return L.Element.all = R.Element.all; - end if; + return (if L.Key.all < R.Key.all then False + elsif R.Key.all < L.Key.all then False + else L.Element.all = R.Element.all); end Is_Equal_Node_Node; ------------------------- @@ -856,12 +824,13 @@ package body Ada.Containers.Indefinite_Ordered_Maps is is Node : constant Node_Access := Container.Tree.First; It : constant Iterator := (Container'Unrestricted_Access, Node); - begin return It; end Iterate; - function Iterate (Container : Map; Start : Cursor) + function Iterate + (Container : Map; + Start : Cursor) return Map_Iterator_Interfaces.Reversible_Iterator'class is It : constant Iterator := (Container'Unrestricted_Access, Start.Node); @@ -897,24 +866,17 @@ package body Ada.Containers.Indefinite_Ordered_Maps is function Last (Container : Map) return Cursor is T : Tree_Type renames Container.Tree; - begin - if T.Last = null then - return No_Element; - end if; - - return Cursor'(Container'Unrestricted_Access, T.Last); + return (if T.Last = null then No_Element + else Cursor'(Container'Unrestricted_Access, T.Last)); end Last; function Last (Object : Iterator) return Cursor is M : constant Map_Access := Object.Container; N : constant Node_Access := M.Tree.Last; begin - if N = null then - return No_Element; - else - return Cursor'(Object.Container.all'Unchecked_Access, N); - end if; + return (if N = null then No_Element + else Cursor'(Object.Container.all'Unchecked_Access, N)); end Last; ------------------ @@ -969,8 +931,7 @@ package body Ada.Containers.Indefinite_Ordered_Maps is -- Move -- ---------- - procedure Move is - new Tree_Operations.Generic_Move (Clear); + procedure Move is new Tree_Operations.Generic_Move (Clear); procedure Move (Target : in out Map; Source : in out Map) is begin @@ -996,13 +957,9 @@ package body Ada.Containers.Indefinite_Ordered_Maps is declare Node : constant Node_Access := Tree_Operations.Next (Position.Node); - begin - if Node = null then - return No_Element; - else - return Cursor'(Position.Container, Node); - end if; + return (if Node = null then No_Element + else Cursor'(Position.Container, Node)); end; end Next; @@ -1016,11 +973,8 @@ package body Ada.Containers.Indefinite_Ordered_Maps is Position : Cursor) return Cursor is begin - if Position.Node = null then - return No_Element; - else - return (Object.Container, Tree_Operations.Next (Position.Node)); - end if; + return (if Position.Node = null then No_Element + else (Object.Container, Tree_Operations.Next (Position.Node))); end Next; ------------ @@ -1051,13 +1005,9 @@ package body Ada.Containers.Indefinite_Ordered_Maps is declare Node : constant Node_Access := Tree_Operations.Previous (Position.Node); - begin - if Node = null then - return No_Element; - end if; - - return Cursor'(Position.Container, Node); + return (if Node = null then No_Element + else Cursor'(Position.Container, Node)); end; end Previous; @@ -1071,11 +1021,9 @@ package body Ada.Containers.Indefinite_Ordered_Maps is Position : Cursor) return Cursor is begin - if Position.Node = null then - return No_Element; - else - return (Object.Container, Tree_Operations.Previous (Position.Node)); - end if; + return + (if Position.Node = null then No_Element + else (Object.Container, Tree_Operations.Previous (Position.Node))); end Previous; ------------------- @@ -1203,8 +1151,10 @@ package body Ada.Containers.Indefinite_Ordered_Maps is Key : Key_Type) return Reference_Type is + Node : aliased Element_Type := Element (Container, Key); + begin - return (Element => Container.Element (Key)'Unrestricted_Access); + return (Element => Node'Access); end Reference; ------------- diff --git a/gcc/ada/a-ciorse.adb b/gcc/ada/a-ciorse.adb index a330ed8b6c5..4257f0974e6 100644 --- a/gcc/ada/a-ciorse.adb +++ b/gcc/ada/a-ciorse.adb @@ -314,8 +314,7 @@ package body Ada.Containers.Indefinite_Ordered_Sets is -- Adjust -- ------------ - procedure Adjust is - new Tree_Operations.Generic_Adjust (Copy_Tree); + procedure Adjust is new Tree_Operations.Generic_Adjust (Copy_Tree); procedure Adjust (Container : in out Set) is begin @@ -329,13 +328,9 @@ package body Ada.Containers.Indefinite_Ordered_Sets is function Ceiling (Container : Set; Item : Element_Type) return Cursor is Node : constant Node_Access := Element_Keys.Ceiling (Container.Tree, Item); - begin - if Node = null then - return No_Element; - end if; - - return Cursor'(Container'Unrestricted_Access, Node); + return (if Node = null then No_Element + else Cursor'(Container'Unrestricted_Access, Node)); end Ceiling; ----------- @@ -433,7 +428,6 @@ package body Ada.Containers.Indefinite_Ordered_Sets is procedure Delete_First (Container : in out Set) is Tree : Tree_Type renames Container.Tree; X : Node_Access := Tree.First; - begin if X /= null then Tree_Operations.Delete_Node_Sans_Free (Tree, X); @@ -448,7 +442,6 @@ package body Ada.Containers.Indefinite_Ordered_Sets is procedure Delete_Last (Container : in out Set) is Tree : Tree_Type renames Container.Tree; X : Node_Access := Tree.Last; - begin if X /= null then Tree_Operations.Delete_Node_Sans_Free (Tree, X); @@ -466,8 +459,7 @@ package body Ada.Containers.Indefinite_Ordered_Sets is end Difference; function Difference (Left, Right : Set) return Set is - Tree : constant Tree_Type := - Set_Ops.Difference (Left.Tree, Right.Tree); + Tree : constant Tree_Type := Set_Ops.Difference (Left.Tree, Right.Tree); begin return Set'(Controlled with Tree); end Difference; @@ -498,9 +490,7 @@ package body Ada.Containers.Indefinite_Ordered_Sets is function Equivalent_Elements (Left, Right : Element_Type) return Boolean is begin - if Left < Right - or else Right < Left - then + if Left < Right or else Right < Left then return False; else return True; @@ -547,7 +537,6 @@ package body Ada.Containers.Indefinite_Ordered_Sets is procedure Exclude (Container : in out Set; Item : Element_Type) is X : Node_Access := Element_Keys.Find (Container.Tree, Item); - begin if X /= null then Tree_Operations.Delete_Node_Sans_Free (Container.Tree, X); @@ -577,11 +566,9 @@ package body Ada.Containers.Indefinite_Ordered_Sets is function First (Container : Set) return Cursor is begin - if Container.Tree.First = null then - return No_Element; - end if; - - return Cursor'(Container'Unrestricted_Access, Container.Tree.First); + return + (if Container.Tree.First = null then No_Element + else Cursor'(Container'Unrestricted_Access, Container.Tree.First)); end First; function First (Object : Iterator) return Cursor is @@ -611,11 +598,8 @@ package body Ada.Containers.Indefinite_Ordered_Sets is Node : constant Node_Access := Element_Keys.Floor (Container.Tree, Item); begin - if Node = null then - return No_Element; - else - return Cursor'(Container'Unrestricted_Access, Node); - end if; + return (if Node = null then No_Element + else Cursor'(Container'Unrestricted_Access, Node)); end Floor; ---------- @@ -685,13 +669,9 @@ package body Ada.Containers.Indefinite_Ordered_Sets is function Ceiling (Container : Set; Key : Key_Type) return Cursor is Node : constant Node_Access := Key_Keys.Ceiling (Container.Tree, Key); - begin - if Node = null then - return No_Element; - end if; - - return Cursor'(Container'Unrestricted_Access, Node); + return (if Node = null then No_Element + else Cursor'(Container'Unrestricted_Access, Node)); end Ceiling; -------------- @@ -741,9 +721,7 @@ package body Ada.Containers.Indefinite_Ordered_Sets is function Equivalent_Keys (Left, Right : Key_Type) return Boolean is begin - if Left < Right - or else Right < Left - then + if Left < Right or else Right < Left then return False; else return True; @@ -756,7 +734,6 @@ package body Ada.Containers.Indefinite_Ordered_Sets is procedure Exclude (Container : in out Set; Key : Key_Type) is X : Node_Access := Key_Keys.Find (Container.Tree, Key); - begin if X /= null then Tree_Operations.Delete_Node_Sans_Free (Container.Tree, X); @@ -771,13 +748,9 @@ package body Ada.Containers.Indefinite_Ordered_Sets is function Find (Container : Set; Key : Key_Type) return Cursor is Node : constant Node_Access := Key_Keys.Find (Container.Tree, Key); - begin - if Node = null then - return No_Element; - end if; - - return Cursor'(Container'Unrestricted_Access, Node); + return (if Node = null then No_Element + else Cursor'(Container'Unrestricted_Access, Node)); end Find; ----------- @@ -787,13 +760,9 @@ package body Ada.Containers.Indefinite_Ordered_Sets is function Floor (Container : Set; Key : Key_Type) return Cursor is Node : constant Node_Access := Key_Keys.Floor (Container.Tree, Key); - begin - if Node = null then - return No_Element; - end if; - - return Cursor'(Container'Unrestricted_Access, Node); + return (if Node = null then No_Element + else Cursor'(Container'Unrestricted_Access, Node)); end Floor; ------------------------- @@ -802,7 +771,8 @@ package body Ada.Containers.Indefinite_Ordered_Sets is function Is_Greater_Key_Node (Left : Key_Type; - Right : Node_Access) return Boolean is + Right : Node_Access) return Boolean + is begin return Key (Right.Element.all) < Left; end Is_Greater_Key_Node; @@ -813,7 +783,8 @@ package body Ada.Containers.Indefinite_Ordered_Sets is function Is_Less_Key_Node (Left : Key_Type; - Right : Node_Access) return Boolean is + Right : Node_Access) return Boolean + is begin return Left < Key (Right.Element.all); end Is_Less_Key_Node; @@ -1179,7 +1150,8 @@ package body Ada.Containers.Indefinite_Ordered_Sets is function Is_Greater_Element_Node (Left : Element_Type; - Right : Node_Access) return Boolean is + Right : Node_Access) return Boolean + is begin -- e > node same as node < e @@ -1192,7 +1164,8 @@ package body Ada.Containers.Indefinite_Ordered_Sets is function Is_Less_Element_Node (Left : Element_Type; - Right : Node_Access) return Boolean is + Right : Node_Access) return Boolean + is begin return Left < Right.Element.all; end Is_Less_Element_Node; @@ -1283,22 +1256,16 @@ package body Ada.Containers.Indefinite_Ordered_Sets is function Last (Container : Set) return Cursor is begin - if Container.Tree.Last = null then - return No_Element; - else - return Cursor'(Container'Unrestricted_Access, Container.Tree.Last); - end if; + return + (if Container.Tree.Last = null then No_Element + else Cursor'(Container'Unrestricted_Access, Container.Tree.Last)); end Last; function Last (Object : Iterator) return Cursor is begin - if Object.Container.Tree.Last = null then - return No_Element; - else - return Cursor'( - Object.Container.all'Unrestricted_Access, - Object.Container.Tree.Last); - end if; + return (if Object.Container.Tree.Last = null then No_Element + else Cursor'(Object.Container.all'Unrestricted_Access, + Object.Container.Tree.Last)); end Last; ------------------ @@ -1336,8 +1303,7 @@ package body Ada.Containers.Indefinite_Ordered_Sets is -- Move -- ---------- - procedure Move is - new Tree_Operations.Generic_Move (Clear); + procedure Move is new Tree_Operations.Generic_Move (Clear); procedure Move (Target : in out Set; Source : in out Set) is begin @@ -1369,13 +1335,9 @@ package body Ada.Containers.Indefinite_Ordered_Sets is declare Node : constant Node_Access := Tree_Operations.Next (Position.Node); - begin - if Node = null then - return No_Element; - end if; - - return Cursor'(Position.Container, Node); + return (if Node = null then No_Element + else Cursor'(Position.Container, Node)); end; end Next; @@ -1431,13 +1393,9 @@ package body Ada.Containers.Indefinite_Ordered_Sets is declare Node : constant Node_Access := Tree_Operations.Previous (Position.Node); - begin - if Node = null then - return No_Element; - end if; - - return Cursor'(Position.Container, Node); + return (if Node = null then No_Element + else Cursor'(Position.Container, Node)); end; end Previous; @@ -1608,15 +1566,15 @@ package body Ada.Containers.Indefinite_Ordered_Sets is pragma Inline (New_Node); procedure Local_Insert_Post is - new Element_Keys.Generic_Insert_Post (New_Node); + new Element_Keys.Generic_Insert_Post (New_Node); procedure Local_Insert_Sans_Hint is - new Element_Keys.Generic_Conditional_Insert (Local_Insert_Post); + new Element_Keys.Generic_Conditional_Insert (Local_Insert_Post); procedure Local_Insert_With_Hint is - new Element_Keys.Generic_Conditional_Insert_With_Hint - (Local_Insert_Post, - Local_Insert_Sans_Hint); + new Element_Keys.Generic_Conditional_Insert_With_Hint + (Local_Insert_Post, + Local_Insert_Sans_Hint); -------------- -- New_Node -- @@ -1629,7 +1587,6 @@ package body Ada.Containers.Indefinite_Ordered_Sets is Node.Parent := null; Node.Right := null; Node.Left := null; - return Node; end New_Node; @@ -1829,12 +1786,10 @@ package body Ada.Containers.Indefinite_Ordered_Sets is ------------ function To_Set (New_Item : Element_Type) return Set is - Tree : Tree_Type; - + Tree : Tree_Type; Node : Node_Access; Inserted : Boolean; pragma Unreferenced (Node, Inserted); - begin Insert_Sans_Hint (Tree, New_Item, Node, Inserted); return Set'(Controlled with Tree); diff --git a/gcc/ada/a-comutr.adb b/gcc/ada/a-comutr.adb index 0fcb3d6d51c..86be79ffc35 100644 --- a/gcc/ada/a-comutr.adb +++ b/gcc/ada/a-comutr.adb @@ -48,16 +48,16 @@ package body Ada.Containers.Multiway_Trees is overriding function First (Object : Iterator) return Cursor; overriding function Next - (Object : Iterator; + (Object : Iterator; Position : Cursor) return Cursor; overriding function First (Object : Child_Iterator) return Cursor; overriding function Next - (Object : Child_Iterator; + (Object : Child_Iterator; Position : Cursor) return Cursor; overriding function Previous - (Object : Child_Iterator; + (Object : Child_Iterator; Position : Cursor) return Cursor; overriding function Last (Object : Child_Iterator) return Cursor; @@ -327,11 +327,8 @@ package body Ada.Containers.Multiway_Trees is function Child_Count (Parent : Cursor) return Count_Type is begin - if Parent = No_Element then - return 0; - else - return Child_Count (Parent.Node.Children); - end if; + return (if Parent = No_Element + then 0 else Child_Count (Parent.Node.Children)); end Child_Count; function Child_Count (Children : Children_Type) return Count_Type is @@ -1010,12 +1007,10 @@ package body Ada.Containers.Multiway_Trees is -- raise Program_Error with "Position cursor not in container"; -- end if; - if Is_Root (Position) then - Result := Find_In_Children (Position.Node, Item); - - else - Result := Find_In_Subtree (Position.Node, Item); - end if; + Result := + (if Is_Root (Position) + then Find_In_Children (Position.Node, Item) + else Find_In_Subtree (Position.Node, Item)); if Result = null then return No_Element; @@ -1437,7 +1432,7 @@ package body Ada.Containers.Multiway_Trees is function Iterate_Children (Container : Tree; Parent : Cursor) - return Tree_Iterator_Interfaces.Reversible_Iterator'Class + return Tree_Iterator_Interfaces.Reversible_Iterator'Class is pragma Unreferenced (Container); begin @@ -1457,8 +1452,8 @@ package body Ada.Containers.Multiway_Trees is end Iterate_Subtree; procedure Iterate_Subtree - (Position : Cursor; - Process : not null access procedure (Position : Cursor)) + (Position : Cursor; + Process : not null access procedure (Position : Cursor)) is begin if Position = No_Element then @@ -1515,6 +1510,7 @@ package body Ada.Containers.Multiway_Trees is function Last_Child (Parent : Cursor) return Cursor is Node : Tree_Node_Access; + begin if Parent = No_Element then raise Constraint_Error with "Parent cursor has no element"; @@ -1575,7 +1571,7 @@ package body Ada.Containers.Multiway_Trees is ---------- function Next - (Object : Iterator; + (Object : Iterator; Position : Cursor) return Cursor is T : Tree renames Position.Container.all; @@ -1635,18 +1631,12 @@ package body Ada.Containers.Multiway_Trees is end Next; function Next - (Object : Child_Iterator; + (Object : Child_Iterator; Position : Cursor) return Cursor is C : constant Tree_Node_Access := Position.Node.Next; - begin - if C = null then - return No_Element; - - else - return (Object.Container, C); - end if; + return (if C = null then No_Element else (Object.Container, C)); end Next; ------------------ @@ -1773,18 +1763,12 @@ package body Ada.Containers.Multiway_Trees is -------------- overriding function Previous - (Object : Child_Iterator; + (Object : Child_Iterator; Position : Cursor) return Cursor is C : constant Tree_Node_Access := Position.Node.Prev; - begin - if C = null then - return No_Element; - - else - return (Object.Container, C); - end if; + return (if C = null then No_Element else (Object.Container, C)); end Previous; ---------------------- @@ -1793,15 +1777,10 @@ package body Ada.Containers.Multiway_Trees is function Previous_Sibling (Position : Cursor) return Cursor is begin - if Position = No_Element then - return No_Element; - end if; - - if Position.Node.Prev = null then - return No_Element; - end if; - - return Cursor'(Position.Container, Position.Node.Prev); + return + (if Position = No_Element then No_Element + elsif Position.Node.Prev = null then No_Element + else Cursor'(Position.Container, Position.Node.Prev)); end Previous_Sibling; procedure Previous_Sibling (Position : in out Cursor) is diff --git a/gcc/ada/a-coorse.adb b/gcc/ada/a-coorse.adb index d52ed67c9a0..915eed62117 100644 --- a/gcc/ada/a-coorse.adb +++ b/gcc/ada/a-coorse.adb @@ -288,13 +288,9 @@ package body Ada.Containers.Ordered_Sets is function Ceiling (Container : Set; Item : Element_Type) return Cursor is Node : constant Node_Access := Element_Keys.Ceiling (Container.Tree, Item); - begin - if Node = null then - return No_Element; - end if; - - return Cursor'(Container'Unrestricted_Access, Node); + return (if Node = null then No_Element + else Cursor'(Container'Unrestricted_Access, Node)); end Ceiling; ----------- @@ -385,7 +381,6 @@ package body Ada.Containers.Ordered_Sets is procedure Delete_First (Container : in out Set) is Tree : Tree_Type renames Container.Tree; X : Node_Access := Tree.First; - begin if X /= null then Tree_Operations.Delete_Node_Sans_Free (Tree, X); @@ -400,7 +395,6 @@ package body Ada.Containers.Ordered_Sets is procedure Delete_Last (Container : in out Set) is Tree : Tree_Type renames Container.Tree; X : Node_Access := Tree.Last; - begin if X /= null then Tree_Operations.Delete_Node_Sans_Free (Tree, X); @@ -446,13 +440,7 @@ package body Ada.Containers.Ordered_Sets is function Equivalent_Elements (Left, Right : Element_Type) return Boolean is begin - if Left < Right - or else Right < Left - then - return False; - else - return True; - end if; + return (if Left < Right or else Right < Left then False else True); end Equivalent_Elements; --------------------- @@ -472,13 +460,9 @@ package body Ada.Containers.Ordered_Sets is function Is_Equivalent_Node_Node (L, R : Node_Access) return Boolean is begin - if L.Element < R.Element then - return False; - elsif R.Element < L.Element then - return False; - else - return True; - end if; + return (if L.Element < R.Element then False + elsif R.Element < L.Element then False + else True); end Is_Equivalent_Node_Node; -- Start of processing for Equivalent_Sets @@ -508,13 +492,9 @@ package body Ada.Containers.Ordered_Sets is function Find (Container : Set; Item : Element_Type) return Cursor is Node : constant Node_Access := Element_Keys.Find (Container.Tree, Item); - begin - if Node = null then - return No_Element; - end if; - - return Cursor'(Container'Unrestricted_Access, Node); + return (if Node = null then No_Element + else Cursor'(Container'Unrestricted_Access, Node)); end Find; ----------- @@ -523,23 +503,16 @@ package body Ada.Containers.Ordered_Sets is function First (Container : Set) return Cursor is begin - if Container.Tree.First = null then - return No_Element; - end if; - - return Cursor'(Container'Unrestricted_Access, Container.Tree.First); + return + (if Container.Tree.First = null then No_Element + else Cursor'(Container'Unrestricted_Access, Container.Tree.First)); end First; function First (Object : Iterator) return Cursor is begin - if Object.Container = null then - return No_Element; - else - return - Cursor'( - Object.Container.all'Unrestricted_Access, - Object.Container.Tree.First); - end if; + return (if Object.Container = null then No_Element + else Cursor'(Object.Container.all'Unrestricted_Access, + Object.Container.Tree.First)); end First; ------------------- @@ -562,13 +535,9 @@ package body Ada.Containers.Ordered_Sets is function Floor (Container : Set; Item : Element_Type) return Cursor is Node : constant Node_Access := Element_Keys.Floor (Container.Tree, Item); - begin - if Node = null then - return No_Element; - end if; - - return Cursor'(Container'Unrestricted_Access, Node); + return (if Node = null then No_Element + else Cursor'(Container'Unrestricted_Access, Node)); end Floor; ---------- @@ -578,13 +547,11 @@ package body Ada.Containers.Ordered_Sets is procedure Free (X : in out Node_Access) is procedure Deallocate is new Ada.Unchecked_Deallocation (Node_Type, Node_Access); - begin if X /= null then X.Parent := X; - X.Left := X; - X.Right := X; - + X.Left := X; + X.Right := X; Deallocate (X); end if; end Free; @@ -627,13 +594,9 @@ package body Ada.Containers.Ordered_Sets is function Ceiling (Container : Set; Key : Key_Type) return Cursor is Node : constant Node_Access := Key_Keys.Ceiling (Container.Tree, Key); - begin - if Node = null then - return No_Element; - end if; - - return Cursor'(Container'Unrestricted_Access, Node); + return (if Node = null then No_Element + else Cursor'(Container'Unrestricted_Access, Node)); end Ceiling; -------------- @@ -683,13 +646,7 @@ package body Ada.Containers.Ordered_Sets is function Equivalent_Keys (Left, Right : Key_Type) return Boolean is begin - if Left < Right - or else Right < Left - then - return False; - else - return True; - end if; + return (if Left < Right or else Right < Left then False else True); end Equivalent_Keys; ------------- @@ -698,7 +655,6 @@ package body Ada.Containers.Ordered_Sets is procedure Exclude (Container : in out Set; Key : Key_Type) is X : Node_Access := Key_Keys.Find (Container.Tree, Key); - begin if X /= null then Delete_Node_Sans_Free (Container.Tree, X); @@ -712,13 +668,9 @@ package body Ada.Containers.Ordered_Sets is function Find (Container : Set; Key : Key_Type) return Cursor is Node : constant Node_Access := Key_Keys.Find (Container.Tree, Key); - begin - if Node = null then - return No_Element; - end if; - - return Cursor'(Container'Unrestricted_Access, Node); + return (if Node = null then No_Element + else Cursor'(Container'Unrestricted_Access, Node)); end Find; ----------- @@ -727,13 +679,9 @@ package body Ada.Containers.Ordered_Sets is function Floor (Container : Set; Key : Key_Type) return Cursor is Node : constant Node_Access := Key_Keys.Floor (Container.Tree, Key); - begin - if Node = null then - return No_Element; - end if; - - return Cursor'(Container'Unrestricted_Access, Node); + return (if Node = null then No_Element + else Cursor'(Container'Unrestricted_Access, Node)); end Floor; ------------------------- @@ -1214,22 +1162,16 @@ package body Ada.Containers.Ordered_Sets is function Last (Container : Set) return Cursor is begin - if Container.Tree.Last = null then - return No_Element; - else - return Cursor'(Container'Unrestricted_Access, Container.Tree.Last); - end if; + return + (if Container.Tree.Last = null then No_Element + else Cursor'(Container'Unrestricted_Access, Container.Tree.Last)); end Last; function Last (Object : Iterator) return Cursor is begin - if Object.Container = null then - return No_Element; - else - return Cursor'( - Object.Container.all'Unrestricted_Access, - Object.Container.Tree.Last); - end if; + return (if Object.Container = null then No_Element + else Cursor'(Object.Container.all'Unrestricted_Access, + Object.Container.Tree.Last)); end Last; ------------------ @@ -1267,8 +1209,7 @@ package body Ada.Containers.Ordered_Sets is -- Move -- ---------- - procedure Move is - new Tree_Operations.Generic_Move (Clear); + procedure Move is new Tree_Operations.Generic_Move (Clear); procedure Move (Target : in out Set; Source : in out Set) is begin @@ -1291,13 +1232,9 @@ package body Ada.Containers.Ordered_Sets is declare Node : constant Node_Access := Tree_Operations.Next (Position.Node); - begin - if Node = null then - return No_Element; - end if; - - return Cursor'(Position.Container, Node); + return (if Node = null then No_Element + else Cursor'(Position.Container, Node)); end; end Next; @@ -1347,11 +1284,8 @@ package body Ada.Containers.Ordered_Sets is Node : constant Node_Access := Tree_Operations.Previous (Position.Node); begin - if Node = null then - return No_Element; - else - return Cursor'(Position.Container, Node); - end if; + return (if Node = null then No_Element + else Cursor'(Position.Container, Node)); end; end Previous; @@ -1429,11 +1363,9 @@ package body Ada.Containers.Ordered_Sets is (Stream : not null access Root_Stream_Type'Class) return Node_Access is Node : Node_Access := new Node_Type; - begin Element_Type'Read (Stream, Node.Element); return Node; - exception when others => Free (Node); @@ -1532,11 +1464,10 @@ package body Ada.Containers.Ordered_Sets is function New_Node return Node_Access is begin Node.Element := Item; - Node.Color := Red; - Node.Parent := null; - Node.Right := null; - Node.Left := null; - + Node.Color := Red; + Node.Parent := null; + Node.Right := null; + Node.Left := null; return Node; end New_Node; @@ -1547,9 +1478,7 @@ package body Ada.Containers.Ordered_Sets is -- Start of processing for Replace_Element begin - if Item < Node.Element - or else Node.Element < Item - then + if Item < Node.Element or else Node.Element < Item then null; else diff --git a/gcc/ada/a-cuprqu.adb b/gcc/ada/a-cuprqu.adb index 2d11a2621b3..385aa5ce7d2 100644 --- a/gcc/ada/a-cuprqu.adb +++ b/gcc/ada/a-cuprqu.adb @@ -65,6 +65,24 @@ package body Ada.Containers.Unbounded_Priority_Queues is Free (X); end Dequeue; + procedure Dequeue + (List : in out List_Type; + At_Least : Queue_Priority; + Element : in out Queue_Interfaces.Element_Type; + Success : out Boolean) + is + begin + if List.Length = 0 + or else not Before (At_Least, Get_Priority (List.First.Element)) + then + Success := False; + return; + end if; + + List.Dequeue (Element); + Success := True; + end Dequeue; + ------------- -- Enqueue -- ------------- @@ -132,22 +150,6 @@ package body Ada.Containers.Unbounded_Priority_Queues is end loop; end Finalize; - ------------------------ - -- Have_High_Priority -- - ------------------------ - - -- ??? - -- function Have_High_Priority - -- (List : List_Type; - -- Low_Priority : Queue_Priority) return Boolean - -- is - -- begin - -- if List.Length = 0 then - -- return False; - -- end if; - -- return Before (Get_Priority (List.First.Element), Low_Priority); - -- end Have_High_Priority; - ------------ -- Length -- ------------ @@ -190,14 +192,18 @@ package body Ada.Containers.Unbounded_Priority_Queues is List.Dequeue (Element); end Dequeue; - -- ??? - -- entry Dequeue_Only_High_Priority - -- (Low_Priority : Queue_Priority; - -- Element : out Queue_Interfaces.Element_Type) when True - -- is - -- begin - -- null; - -- end Dequeue_Only_High_Priority; + -------------------------------- + -- Dequeue_Only_High_Priority -- + -------------------------------- + + procedure Dequeue_Only_High_Priority + (At_Least : Queue_Priority; + Element : in out Queue_Interfaces.Element_Type; + Success : out Boolean) + is + begin + List.Dequeue (At_Least, Element, Success); + end Dequeue_Only_High_Priority; ------------- -- Enqueue -- diff --git a/gcc/ada/a-cuprqu.ads b/gcc/ada/a-cuprqu.ads index d31c8824458..33db4a281f3 100644 --- a/gcc/ada/a-cuprqu.ads +++ b/gcc/ada/a-cuprqu.ads @@ -68,6 +68,12 @@ package Ada.Containers.Unbounded_Priority_Queues is (List : in out List_Type; Element : out Queue_Interfaces.Element_Type); + procedure Dequeue + (List : in out List_Type; + At_Least : Queue_Priority; + Element : in out Queue_Interfaces.Element_Type; + Success : out Boolean); + function Length (List : List_Type) return Count_Type; function Max_Length (List : List_Type) return Count_Type; @@ -91,36 +97,37 @@ package Ada.Containers.Unbounded_Priority_Queues is overriding procedure Finalize (List : in out List_Type); - -- ??? - -- not overriding - -- function Have_High_Priority - -- (List : List_Type; - -- Low_Priority : Queue_Priority) return Boolean; - end Implementation; protected type Queue (Ceiling : System.Any_Priority := Default_Ceiling) - -- ??? - -- with Priority => Ceiling is new Queue_Interfaces.Queue with - is new Queue_Interfaces.Queue with + -- ??? + -- with Priority => Ceiling is new Queue_Interfaces.Queue with + is new Queue_Interfaces.Queue with - overriding - entry Enqueue (New_Item : Queue_Interfaces.Element_Type); + overriding + entry Enqueue (New_Item : Queue_Interfaces.Element_Type); - overriding - entry Dequeue (Element : out Queue_Interfaces.Element_Type); + overriding + entry Dequeue (Element : out Queue_Interfaces.Element_Type); - -- ??? - -- not overriding - -- entry Dequeue_Only_High_Priority - -- (Low_Priority : Queue_Priority; - -- Element : out Queue_Interfaces.Element_Type); + -- The priority queue operation Dequeue_Only_High_Priority had been a + -- protected entry in early drafts of AI05-0159, but it was discovered + -- that that operation as specified was not in fact implementable. The + -- operation was changed from an entry to a protected procedure per the + -- ARG meeting in Edinburgh (June 2011), with a different signature and + -- semantics. - overriding - function Current_Use return Count_Type; + not overriding + procedure Dequeue_Only_High_Priority + (At_Least : Queue_Priority; + Element : in out Queue_Interfaces.Element_Type; + Success : out Boolean); - overriding - function Peak_Use return Count_Type; + overriding + function Current_Use return Count_Type; + + overriding + function Peak_Use return Count_Type; private diff --git a/gcc/ada/einfo.ads b/gcc/ada/einfo.ads index 93d914fd855..019f2f37133 100644 --- a/gcc/ada/einfo.ads +++ b/gcc/ada/einfo.ads @@ -2475,11 +2475,11 @@ package Einfo is -- Is_Local_Anonymous_Access (Flag194) -- Present in access types. Set for an anonymous access type to indicate -- that the type is created for a record component with an access --- definition, an array component, or (pre-Ada2012) a stand-alone object. +-- definition, an array component, or (pre-Ada 2012) a standalone object. -- Such anonymous types have an accessibility level equal to that of the -- declaration in which they appear, unlike the anonymous access types -- that are created for access parameters, access discriminants, and --- (as of Ada2012) stand-alone objects. +-- (as of Ada 2012) stand-alone objects. -- Is_Machine_Code_Subprogram (Flag137) -- Present in subprogram entities. Set to indicate that the subprogram diff --git a/gcc/ada/exp_attr.adb b/gcc/ada/exp_attr.adb index 897844bb8e4..db8f6a30d5d 100644 --- a/gcc/ada/exp_attr.adb +++ b/gcc/ada/exp_attr.adb @@ -678,7 +678,7 @@ package body Exp_Attr is case Id is - -- Attributes related to Ada2012 iterators (placeholder ???) + -- Attributes related to Ada 2012 iterators (placeholder ???) when Attribute_Constant_Indexing => null; when Attribute_Default_Iterator => null; diff --git a/gcc/ada/exp_ch3.adb b/gcc/ada/exp_ch3.adb index fecbf5ce26b..ef769758e57 100644 --- a/gcc/ada/exp_ch3.adb +++ b/gcc/ada/exp_ch3.adb @@ -6289,7 +6289,7 @@ package body Exp_Ch3 is end if; end if; - -- In the non-tagged case, ever since Ada83 an equality function must + -- In the non-tagged case, ever since Ada 83 an equality function must -- be provided for variant records that are not unchecked unions. -- In Ada 2012 the equality function composes, and thus must be built -- explicitly just as for tagged records. diff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb index c099933c310..677eec74dd5 100644 --- a/gcc/ada/exp_ch4.adb +++ b/gcc/ada/exp_ch4.adb @@ -765,7 +765,7 @@ package body Exp_Ch4 is -- Start of processing for Expand_Allocator_Expression begin - -- In the case of an Ada2012 allocator whose initial value comes from a + -- In the case of an Ada 2012 allocator whose initial value comes from a -- function call, pass "the accessibility level determined by the point -- of call" (AI05-0234) to the function. Conceptually, this belongs in -- Expand_Call but it couldn't be done there (because the Etype of the diff --git a/gcc/ada/exp_ch7.adb b/gcc/ada/exp_ch7.adb index c7ea703d272..27b1cd764e0 100644 --- a/gcc/ada/exp_ch7.adb +++ b/gcc/ada/exp_ch7.adb @@ -3842,7 +3842,7 @@ package body Exp_Ch7 is ---------------------------------- -- Add call to Activate_Tasks if there are tasks declared and the package - -- has no body. Note that in Ada83, this may result in premature activation + -- has no body. Note that in Ada 83 this may result in premature activation -- of some tasks, given that we cannot tell whether a body will eventually -- appear. diff --git a/gcc/ada/exp_ch9.adb b/gcc/ada/exp_ch9.adb index fc70238aedb..433ee6b3a74 100644 --- a/gcc/ada/exp_ch9.adb +++ b/gcc/ada/exp_ch9.adb @@ -178,7 +178,7 @@ package body Exp_Ch9 is -- body or an accept body. The renamed object is a component of the -- parameter block that is a parameter in the entry call. - -- In Ada2012, If the formal is an incomplete tagged type, the renaming + -- In Ada 2012, if the formal is an incomplete tagged type, the renaming -- does not dereference the corresponding component to prevent an illegal -- use of the incomplete type (AI05-0151). @@ -11857,7 +11857,7 @@ package body Exp_Ch9 is S : Entity_Id; begin - -- In Ada2005, the master is the innermost enclosing scope that is not + -- In Ada 2005, the master is the innermost enclosing scope that is not -- transient. If the enclosing block is the rewriting of a call or the -- scope is an extended return statement this is valid master. The -- master in an extended return is only used within the return, and is diff --git a/gcc/ada/exp_ch9.ads b/gcc/ada/exp_ch9.ads index 13e3f796ef0..ea2fb8e7916 100644 --- a/gcc/ada/exp_ch9.ads +++ b/gcc/ada/exp_ch9.ads @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 1992-2010, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2011, 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- -- @@ -266,7 +266,7 @@ package Exp_Ch9 is function Find_Master_Scope (E : Entity_Id) return Entity_Id; -- When a type includes tasks, a master entity is created in the scope, to -- be used by the runtime during activation. In general the master is the - -- immediate scope in which the type is declared, but in Ada2005, in the + -- immediate scope in which the type is declared, but in Ada 2005, in the -- presence of synchronized classwide interfaces, the immediate scope of -- an anonymous access type may be a transient scope, which has no run-time -- presence. In this case, the scope of the master is the innermost scope diff --git a/gcc/ada/exp_strm.adb b/gcc/ada/exp_strm.adb index c88c789432e..987556a84ad 100644 --- a/gcc/ada/exp_strm.adb +++ b/gcc/ada/exp_strm.adb @@ -1592,7 +1592,7 @@ package body Exp_Strm is begin -- (Ada 2005: AI-441): Set the null-excluding attribute because it has - -- no semantic meaning in Ada 95 but it is a requirement in Ada2005. + -- no semantic meaning in Ada 95 but it is a requirement in Ada 2005. Profile := New_List ( Make_Parameter_Specification (Loc, @@ -1632,7 +1632,7 @@ package body Exp_Strm is -- Construct function specification -- (Ada 2005: AI-441): Set the null-excluding attribute because it has - -- no semantic meaning in Ada 95 but it is a requirement in Ada2005. + -- no semantic meaning in Ada 95 but it is a requirement in Ada 2005. Spec := Make_Function_Specification (Loc, @@ -1676,7 +1676,7 @@ package body Exp_Strm is -- Construct procedure specification -- (Ada 2005: AI-441): Set the null-excluding attribute because it has - -- no semantic meaning in Ada 95 but it is a requirement in Ada2005. + -- no semantic meaning in Ada 95 but it is a requirement in Ada 2005. Spec := Make_Procedure_Specification (Loc, diff --git a/gcc/ada/exp_util.adb b/gcc/ada/exp_util.adb index 295006a29c3..dd58b017d24 100644 --- a/gcc/ada/exp_util.adb +++ b/gcc/ada/exp_util.adb @@ -1921,11 +1921,11 @@ package body Exp_Util is then null; - -- In Ada95 nothing to be done if the type of the expression is limited, + -- In Ada 95 nothing to be done if the type of the expression is limited -- because in this case the expression cannot be copied, and its use can -- only be by reference. - -- In Ada2005, the context can be an object declaration whose expression + -- In Ada 2005 the context can be an object declaration whose expression -- is a function that returns in place. If the nominal subtype has -- unknown discriminants, the call still provides constraints on the -- object, and we have to create an actual subtype from it. diff --git a/gcc/ada/freeze.adb b/gcc/ada/freeze.adb index e8078648892..7d1dc1fc212 100644 --- a/gcc/ada/freeze.adb +++ b/gcc/ada/freeze.adb @@ -1616,9 +1616,9 @@ package body Freeze is -- Start of processing for Check_Current_Instance begin - -- In Ada95, the (imprecise) rule is that the current instance of a - -- limited type is aliased. In Ada2005, limitedness must be explicit: - -- either a tagged type, or a limited record. + -- In Ada 95, the (imprecise) rule is that the current instance of a + -- limited type is aliased. In Ada 2005, limitedness must be + -- explicit: either a tagged type, or a limited record. if Is_Limited_Type (Rec_Type) and then (Ada_Version < Ada_2005 or else Is_Tagged_Type (Rec_Type)) diff --git a/gcc/ada/g-debpoo.ads b/gcc/ada/g-debpoo.ads index 7e610c240cc..e87c0e4b18d 100644 --- a/gcc/ada/g-debpoo.ads +++ b/gcc/ada/g-debpoo.ads @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 1992-2009, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2011, 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,7 +29,7 @@ -- -- ------------------------------------------------------------------------------ --- This packages provides a special implementation of the Ada95 storage pools +-- This packages provides a special implementation of the Ada 95 storage pools -- The goal of this debug pool is to detect incorrect uses of memory -- (multiple deallocations, access to invalid memory,...). Errors are reported diff --git a/gcc/ada/g-trasym-unimplemented.adb b/gcc/ada/g-trasym-unimplemented.adb deleted file mode 100644 index f020fff497a..00000000000 --- a/gcc/ada/g-trasym-unimplemented.adb +++ /dev/null @@ -1,70 +0,0 @@ ------------------------------------------------------------------------------- --- -- --- GNAT RUN-TIME COMPONENTS -- --- -- --- G N A T . T R A C E B A C K . S Y M B O L I C -- --- -- --- B o d y -- --- -- --- Copyright (C) 1999-2010, AdaCore -- --- -- --- GNAT is free software; you can redistribute it and/or modify it under -- --- terms of the GNU General Public License as published by the Free Soft- -- --- ware Foundation; either version 3, or (at your option) any later ver- -- --- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- --- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- --- or FITNESS FOR A PARTICULAR PURPOSE. -- --- -- --- As a special exception under Section 7 of GPL version 3, you are granted -- --- additional permissions described in the GCC Runtime Library Exception, -- --- version 3.1, as published by the Free Software Foundation. -- --- -- --- You should have received a copy of the GNU General Public License and -- --- a copy of the GCC Runtime Library Exception along with this program; -- --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- --- <http://www.gnu.org/licenses/>. -- --- -- --- GNAT was originally developed by the GNAT team at New York University. -- --- Extensive contributions were provided by Ada Core Technologies Inc. -- --- -- ------------------------------------------------------------------------------- - --- Version used on unimplemented targets - --- Run-time symbolic traceback is currently supported on the following --- targets: - --- HP-UX --- IRIX --- GNU/Linux x86 --- AIX --- Solaris sparc --- Tru64 --- OpenVMS/Alpha --- Windows NT/XP/Vista - --- This version is used on all other targets, it generates a warning at --- compile time if it is with'ed, and the bodies generate messages saying --- that the functions are not implemented. - -package body GNAT.Traceback.Symbolic is - - ------------------------ - -- Symbolic_Traceback -- - ------------------------ - - function Symbolic_Traceback (Traceback : Tracebacks_Array) return String - is - pragma Unreferenced (Traceback); - begin - return "Symbolic_Traceback not implemented on this target"; - end Symbolic_Traceback; - - function Symbolic_Traceback (E : Exception_Occurrence) return String - is - pragma Unreferenced (E); - begin - return "Symbolic_Traceback not implemented on this target"; - end Symbolic_Traceback; - -end GNAT.Traceback.Symbolic; diff --git a/gcc/ada/g-trasym-unimplemented.ads b/gcc/ada/g-trasym-unimplemented.ads deleted file mode 100644 index 8d1f2eeb725..00000000000 --- a/gcc/ada/g-trasym-unimplemented.ads +++ /dev/null @@ -1,64 +0,0 @@ ------------------------------------------------------------------------------- --- -- --- GNAT RUN-TIME COMPONENTS -- --- -- --- G N A T . T R A C E B A C K . S Y M B O L I C -- --- -- --- S p e c -- --- -- --- Copyright (C) 1999-2010, AdaCore -- --- -- --- GNAT is free software; you can redistribute it and/or modify it under -- --- terms of the GNU General Public License as published by the Free Soft- -- --- ware Foundation; either version 3, or (at your option) any later ver- -- --- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- --- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- --- or FITNESS FOR A PARTICULAR PURPOSE. -- --- -- --- As a special exception under Section 7 of GPL version 3, you are granted -- --- additional permissions described in the GCC Runtime Library Exception, -- --- version 3.1, as published by the Free Software Foundation. -- --- -- --- You should have received a copy of the GNU General Public License and -- --- a copy of the GCC Runtime Library Exception along with this program; -- --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- --- <http://www.gnu.org/licenses/>. -- --- -- --- GNAT was originally developed by the GNAT team at New York University. -- --- Extensive contributions were provided by Ada Core Technologies Inc. -- --- -- ------------------------------------------------------------------------------- - --- Version used on unimplemented targets - --- Run-time symbolic traceback is currently supported on the following --- targets: - --- HP-UX hppa and ia64 --- IRIX --- GNU/Linux x86, x86_64, ia64 --- AIX --- Solaris sparc and x86 --- Tru64 --- OpenVMS/Alpha --- Windows NT/XP/Vista - --- This version is used on all other targets, it generates a warning at --- compile time if it is with'ed, and the bodies generate messages saying --- that the functions are not implemented. - -with Ada.Exceptions; use Ada.Exceptions; - -package GNAT.Traceback.Symbolic is - pragma Elaborate_Body; - --- pragma Compile_Time_Warning --- (True, "symbolic traceback not implemented on this target"); - - function Symbolic_Traceback (Traceback : Tracebacks_Array) return String; - -- Build a string containing a symbolic traceback of the given call chain - - function Symbolic_Traceback (E : Exception_Occurrence) return String; - -- Build string containing symbolic traceback of given exception occurrence - -end GNAT.Traceback.Symbolic; diff --git a/gcc/ada/g-trasym.adb b/gcc/ada/g-trasym.adb index 1b1ddffd93a..12793c870c4 100644 --- a/gcc/ada/g-trasym.adb +++ b/gcc/ada/g-trasym.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 1999-2010, AdaCore -- +-- Copyright (C) 1999-2011, 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- -- @@ -29,122 +29,47 @@ -- -- ------------------------------------------------------------------------------ --- Run-time symbolic traceback support +-- This is the default implementation for platforms where the full capability +-- is not supported. It returns tracebacks as lists of "0x..." strings +-- corresponding to the addresses. -with System.Soft_Links; with Ada.Exceptions.Traceback; use Ada.Exceptions.Traceback; +with System.Address_Image; package body GNAT.Traceback.Symbolic is - pragma Linker_Options ("-laddr2line"); - pragma Linker_Options ("-lbfd"); - pragma Linker_Options ("-liberty"); - - package TSL renames System.Soft_Links; - - -- To perform the raw addresses to symbolic form translation we rely on a - -- libaddr2line symbolizer which examines debug info from a provided - -- executable file name, and an absolute path is needed to ensure the file - -- is always found. This is "__gnat_locate_exec_on_path (gnat_argv [0])" - -- for our executable file, a fairly heavy operation so we cache the - -- result. - - Exename : System.Address; - -- Pointer to the name of the executable file to be used on all - -- invocations of the libaddr2line symbolization service. - - Exename_Resolved : Boolean := False; - -- Flag to indicate whether we have performed the executable file name - -- resolution already. Relying on a not null Exename for this purpose - -- would be potentially inefficient as this is what we will get if the - -- resolution attempt fails. - ------------------------ -- Symbolic_Traceback -- ------------------------ - function Symbolic_Traceback (Traceback : Tracebacks_Array) return String is - - procedure convert_addresses - (filename : System.Address; - addrs : System.Address; - n_addrs : Integer; - buf : System.Address; - len : System.Address); - pragma Import (C, convert_addresses, "convert_addresses"); - -- This is the procedure version of the Ada-aware addr2line. It places - -- in BUF a string representing the symbolic translation of the N_ADDRS - -- raw addresses provided in ADDRS, looked up in debug information from - -- FILENAME. LEN points to an integer which contains the size of the - -- BUF buffer at input and the result length at output. - -- - -- This procedure is provided by libaddr2line on targets that support - -- it. A dummy version is in adaint.c for other targets so that build - -- of shared libraries doesn't generate unresolved symbols. - -- - -- Note that this procedure is *not* thread-safe. - - type Argv_Array is array (0 .. 0) of System.Address; - gnat_argv : access Argv_Array; - pragma Import (C, gnat_argv, "gnat_argv"); - - function locate_exec_on_path - (c_exename : System.Address) return System.Address; - pragma Import (C, locate_exec_on_path, "__gnat_locate_exec_on_path"); - - Res : String (1 .. 256 * Traceback'Length); - Len : Integer; - - use type System.Address; - + function Symbolic_Traceback (Traceback : Tracebacks_Array) return String + is begin - -- The symbolic translation of an empty set of addresses is an empty - -- string. - if Traceback'Length = 0 then return ""; - end if; - -- If our input set of raw addresses is not empty, resort to the - -- libaddr2line service to symbolize it all. - - -- Compute, cache and provide the absolute path to our executable file - -- name as the binary file where the relevant debug information is to be - -- found. If the executable file name resolution fails, we have no - -- sensible basis to invoke the symbolizer at all. - - -- Protect all this against concurrent accesses explicitly, as the - -- underlying services are potentially thread unsafe. - - TSL.Lock_Task.all; - - if not Exename_Resolved then - Exename := locate_exec_on_path (gnat_argv (0)); - Exename_Resolved := True; - end if; - - if Exename /= System.Null_Address then - Len := Res'Length; - convert_addresses - (Exename, Traceback'Address, Traceback'Length, - Res (1)'Address, Len'Address); - end if; - - TSL.Unlock_Task.all; - - -- Return what the addr2line symbolizer has produced if we have called - -- it (the executable name resolution succeeded), or an empty string - -- otherwise. - - if Exename /= System.Null_Address then - return Res (1 .. Len); else - return ""; + declare + Img : String := System.Address_Image (Traceback (Traceback'First)); + Result : String (1 .. (Img'Length + 3) * Traceback'Length); + Last : Natural := 0; + begin + for J in Traceback'Range loop + Img := System.Address_Image (Traceback (J)); + Result (Last + 1 .. Last + 2) := "0x"; + Last := Last + 2; + Result (Last + 1 .. Last + Img'Length) := Img; + Last := Last + Img'Length + 1; + Result (Last) := ASCII.LF; + end loop; + + return Result (1 .. Last); + end; end if; - end Symbolic_Traceback; - function Symbolic_Traceback (E : Exception_Occurrence) return String is + function Symbolic_Traceback (E : Exception_Occurrence) return String + is begin return Symbolic_Traceback (Tracebacks (E)); end Symbolic_Traceback; diff --git a/gcc/ada/g-trasym.ads b/gcc/ada/g-trasym.ads index 44d85ae4041..679d236e5f8 100644 --- a/gcc/ada/g-trasym.ads +++ b/gcc/ada/g-trasym.ads @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 1999-2010, AdaCore -- +-- Copyright (C) 1999-2011, 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- -- @@ -31,16 +31,16 @@ -- Run-time symbolic traceback support --- This capability is currently supported on the following targets: +-- The full capability is currently supported on the following targets: --- HP-UX hppa and ia64 +-- HP-UX ia64 -- IRIX -- GNU/Linux x86, x86_64, ia64 --- AIX +-- FreeBSD x86, x86_64 -- Solaris sparc and x86 -- Tru64 --- OpenVMS/Alpha --- Windows NT/XP/Vista +-- OpenVMS Alpha and ia64 +-- Windows -- The routines provided in this package assume that your application has -- been compiled with debugging information turned on, since this information @@ -77,6 +77,10 @@ -- libraries. However, the OS should be at least v7.3-1 and OS patch -- VMS731_TRACE-V0100 must be applied in order to use this package. +-- On platforms where the full capability is not supported, function +-- Symbolic_Traceback return a list of addresses expressed as "0x..." +-- separated by line feed. + with Ada.Exceptions; use Ada.Exceptions; package GNAT.Traceback.Symbolic is diff --git a/gcc/ada/gcc-interface/Makefile.in b/gcc/ada/gcc-interface/Makefile.in index a6c54e8d81d..71bd5ea7993 100644 --- a/gcc/ada/gcc-interface/Makefile.in +++ b/gcc/ada/gcc-interface/Makefile.in @@ -469,8 +469,6 @@ ifeq ($(strip $(filter-out m68k% wrs vx%,$(targ))),) g-socthi.ads<g-socthi-vxworks.ads \ g-socthi.adb<g-socthi-vxworks.adb \ g-stsifd.adb<g-stsifd-sockets.adb \ - g-trasym.ads<g-trasym-unimplemented.ads \ - g-trasym.adb<g-trasym-unimplemented.adb \ system.ads<system-vxworks-m68k.ads TOOLS_TARGET_PAIRS=mlib-tgt-specific.adb<mlib-tgt-specific-vxworks.adb @@ -512,8 +510,6 @@ ifeq ($(strip $(filter-out e500% powerpc% wrs vxworks,$(targ))),) g-socthi.ads<g-socthi-vxworks.ads \ g-socthi.adb<g-socthi-vxworks.adb \ g-stsifd.adb<g-stsifd-sockets.adb \ - g-trasym.ads<g-trasym-unimplemented.ads \ - g-trasym.adb<g-trasym-unimplemented.adb \ $(ATOMICS_TARGET_PAIRS) \ $(ATOMICS_BUILTINS_TARGET_PAIRS) @@ -613,8 +609,6 @@ ifeq ($(strip $(filter-out powerpc% e500v2 wrs vxworksae,$(targ))),) s-vxwext.adb<s-vxwext-noints.adb \ s-vxwext.ads<s-vxwext-vthreads.ads \ s-vxwork.ads<s-vxwork-ppc.ads \ - g-trasym.ads<g-trasym-unimplemented.ads \ - g-trasym.adb<g-trasym-unimplemented.adb \ system.ads<system-vxworks-ppc-vthread.ads \ $(ATOMICS_TARGET_PAIRS) \ $(ATOMICS_BUILTINS_TARGET_PAIRS) @@ -676,8 +670,6 @@ ifeq ($(strip $(filter-out e500% powerpc% wrs vxworksmils,$(targ))),) s-thread.adb<s-thread-ae653.adb \ s-tpopsp.adb<s-tpopsp-vxworks.adb \ s-vxwork.ads<s-vxwork-ppc.ads \ - g-trasym.ads<g-trasym-unimplemented.ads \ - g-trasym.adb<g-trasym-unimplemented.adb \ system.ads<system-vxworks-ppc.ads \ $(ATOMICS_TARGET_PAIRS) \ $(ATOMICS_BUILTINS_TARGET_PAIRS) \ @@ -728,8 +720,6 @@ ifeq ($(strip $(filter-out %86 wrs vxworksae vxworksmils,$(targ))),) s-vxwext.adb<s-vxwext-noints.adb \ s-vxwext.ads<s-vxwext-vthreads.ads \ s-vxwork.ads<s-vxwork-x86.ads \ - g-trasym.ads<g-trasym-unimplemented.ads \ - g-trasym.adb<g-trasym-unimplemented.adb \ $(ATOMICS_TARGET_PAIRS) \ $(X86_TARGET_PAIRS) \ system.ads<system-vxworks-x86.ads @@ -789,8 +779,6 @@ ifeq ($(strip $(filter-out sparc% wrs vx%,$(targ))),) g-socthi.ads<g-socthi-vxworks.ads \ g-socthi.adb<g-socthi-vxworks.adb \ g-stsifd.adb<g-stsifd-sockets.adb \ - g-trasym.ads<g-trasym-unimplemented.ads \ - g-trasym.adb<g-trasym-unimplemented.adb \ system.ads<system-vxworks-sparcv9.ads \ TOOLS_TARGET_PAIRS=\ @@ -825,8 +813,6 @@ ifeq ($(strip $(filter-out %86 wrs vxworks,$(targ))),) g-socthi.ads<g-socthi-vxworks.ads \ g-socthi.adb<g-socthi-vxworks.adb \ g-stsifd.adb<g-stsifd-sockets.adb \ - g-trasym.ads<g-trasym-unimplemented.ads \ - g-trasym.adb<g-trasym-unimplemented.adb \ $(ATOMICS_TARGET_PAIRS) \ $(X86_TARGET_PAIRS) @@ -922,8 +908,6 @@ ifeq ($(strip $(filter-out arm% coff wrs vx%,$(targ))),) g-socthi.ads<g-socthi-vxworks.ads \ g-socthi.adb<g-socthi-vxworks.adb \ g-stsifd.adb<g-stsifd-sockets.adb \ - g-trasym.ads<g-trasym-unimplemented.ads \ - g-trasym.adb<g-trasym-unimplemented.adb \ system.ads<system-vxworks-arm.ads TOOLS_TARGET_PAIRS=\ @@ -960,8 +944,6 @@ ifeq ($(strip $(filter-out mips% wrs vx%,$(targ))),) g-socthi.ads<g-socthi-vxworks.ads \ g-socthi.adb<g-socthi-vxworks.adb \ g-stsifd.adb<g-stsifd-sockets.adb \ - g-trasym.ads<g-trasym-unimplemented.ads \ - g-trasym.adb<g-trasym-unimplemented.adb \ system.ads<system-vxworks-mips.ads TOOLS_TARGET_PAIRS=\ @@ -1271,9 +1253,7 @@ ifeq ($(strip $(filter-out s390% linux%,$(arch) $(osys))),) s-tasinf.ads<s-tasinf-linux.ads \ s-tasinf.adb<s-tasinf-linux.adb \ s-taspri.ads<s-taspri-posix-noaltstack.ads \ - s-tpopsp.adb<s-tpopsp-posix-foreign.adb \ - g-trasym.ads<g-trasym-unimplemented.ads \ - g-trasym.adb<g-trasym-unimplemented.adb + s-tpopsp.adb<s-tpopsp-posix-foreign.adb LIBGNAT_TARGET_PAIRS_32 = \ system.ads<system-linux-s390.ads @@ -1447,9 +1427,7 @@ ifeq ($(strip $(filter-out rtems%,$(osys))),) s-taspri.ads<s-taspri-posix.ads \ s-tpopsp.adb<s-tpopsp-rtems.adb \ s-stchop.adb<s-stchop-rtems.adb \ - s-interr.adb<s-interr-hwint.adb \ - g-trasym.ads<g-trasym-unimplemented.ads \ - g-trasym.adb<g-trasym-unimplemented.adb + s-interr.adb<s-interr-hwint.adb endif ifeq ($(strip $(filter-out alpha% dec osf%,$(targ))),) @@ -1914,8 +1892,6 @@ ifeq ($(strip $(filter-out sparc% linux%,$(arch) $(osys))),) s-tpopsp.adb<s-tpopsp-tls.adb LIBGNAT_TARGET_PAIRS_32 = \ - g-trasym.ads<g-trasym-unimplemented.ads \ - g-trasym.adb<g-trasym-unimplemented.adb \ system.ads<system-linux-sparc.ads LIBGNAT_TARGET_PAIRS_64 = \ @@ -1955,8 +1931,6 @@ ifeq ($(strip $(filter-out hppa% linux%,$(arch) $(osys))),) s-tasinf.adb<s-tasinf-linux.adb \ s-taspri.ads<s-taspri-posix-noaltstack.ads \ s-tpopsp.adb<s-tpopsp-posix-foreign.adb \ - g-trasym.ads<g-trasym-unimplemented.ads \ - g-trasym.adb<g-trasym-unimplemented.adb \ system.ads<system-linux-hppa.ads TOOLS_TARGET_PAIRS = \ @@ -2079,8 +2053,6 @@ ifeq ($(strip $(filter-out alpha% linux%,$(arch) $(osys))),) s-tasinf.adb<s-tasinf-linux.adb \ s-tpopsp.adb<s-tpopsp-posix-foreign.adb \ s-taspri.ads<s-taspri-posix-noaltstack.ads \ - g-trasym.ads<g-trasym-unimplemented.ads \ - g-trasym.adb<g-trasym-unimplemented.adb \ system.ads<system-linux-alpha.ads \ $(ATOMICS_TARGET_PAIRS) \ $(ATOMICS_BUILTINS_TARGET_PAIRS) @@ -2144,9 +2116,7 @@ ifeq ($(strip $(filter-out darwin%,$(osys))),) s-osinte.ads<s-osinte-darwin.ads \ s-taprop.adb<s-taprop-posix.adb \ s-taspri.ads<s-taspri-posix.ads \ - s-tpopsp.adb<s-tpopsp-posix-foreign.adb \ - g-trasym.ads<g-trasym-unimplemented.ads \ - g-trasym.adb<g-trasym-unimplemented.adb + s-tpopsp.adb<s-tpopsp-posix-foreign.adb ifeq ($(strip $(filter-out %86,$(arch))),) LIBGNAT_TARGET_PAIRS += \ diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c index 98d68fe01a6..feb353ba783 100644 --- a/gcc/ada/gcc-interface/decl.c +++ b/gcc/ada/gcc-interface/decl.c @@ -949,10 +949,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) if ((TREE_CODE (gnu_expr) == COMPONENT_REF && TYPE_IS_PADDING_P (TREE_TYPE (TREE_OPERAND (gnu_expr, 0)))) /* Strip useless conversions around the object. */ - || (TREE_CODE (gnu_expr) == NOP_EXPR - && gnat_types_compatible_p - (TREE_TYPE (gnu_expr), - TREE_TYPE (TREE_OPERAND (gnu_expr, 0))))) + || gnat_useless_type_conversion (gnu_expr)) { gnu_expr = TREE_OPERAND (gnu_expr, 0); gnu_type = TREE_TYPE (gnu_expr); diff --git a/gcc/ada/gcc-interface/gigi.h b/gcc/ada/gcc-interface/gigi.h index 30fa99e96d5..f7f9b09272e 100644 --- a/gcc/ada/gcc-interface/gigi.h +++ b/gcc/ada/gcc-interface/gigi.h @@ -450,8 +450,8 @@ extern void set_block_jmpbuf_decl (tree decl); /* Get the setjmp_decl, if any, for the current binding level. */ extern tree get_block_jmpbuf_decl (void); -/* Records a ..._DECL node DECL as belonging to the current lexical scope - and uses GNAT_NODE for location information. */ +/* Record DECL as belonging to the current lexical scope and use GNAT_NODE + for location information and flag propagation. */ extern void gnat_pushdecl (tree decl, Node_Id gnat_node); extern void gnat_init_gcc_eh (void); @@ -479,6 +479,9 @@ extern tree gnat_signed_type (tree type_node); transparently converted to each other. */ extern int gnat_types_compatible_p (tree t1, tree t2); +/* Return true if EXPR is a useless type conversion. */ +extern bool gnat_useless_type_conversion (tree expr); + /* Return true if T, a FUNCTION_TYPE, has the specified list of flags. */ extern bool fntype_same_flags_p (const_tree, tree, bool, bool, bool); @@ -687,9 +690,12 @@ extern tree create_subprog_decl (tree subprog_name, tree asm_name, appearing in the subprogram. */ extern void begin_subprog_body (tree subprog_decl); -/* Finish the definition of the current subprogram BODY and finalize it. */ +/* Finish translating the current subprogram and set its BODY. */ extern void end_subprog_body (tree body); +/* Wrap up compilation of SUBPROG_DECL, a subprogram body. */ +extern void rest_of_subprog_body_compilation (tree subprog_decl); + /* Build a template of type TEMPLATE_TYPE from the array bounds of ARRAY_TYPE. EXPR is an expression that we can use to locate any PLACEHOLDER_EXPRs. Return a constructor for the template. */ diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c index 71e659e265f..af7e9af9608 100644 --- a/gcc/ada/gcc-interface/trans.c +++ b/gcc/ada/gcc-interface/trans.c @@ -34,6 +34,8 @@ #include "libfuncs.h" /* For set_stack_check_libfunc. */ #include "tree-iterator.h" #include "gimple.h" +#include "bitmap.h" +#include "cgraph.h" #include "ada.h" #include "adadecode.h" @@ -125,11 +127,19 @@ DEF_VEC_ALLOC_P(parm_attr,gc); struct GTY(()) language_function { VEC(parm_attr,gc) *parm_attr_cache; + bitmap named_ret_val; + VEC(tree,gc) *other_ret_val; }; #define f_parm_attr_cache \ DECL_STRUCT_FUNCTION (current_function_decl)->language->parm_attr_cache +#define f_named_ret_val \ + DECL_STRUCT_FUNCTION (current_function_decl)->language->named_ret_val + +#define f_other_ret_val \ + DECL_STRUCT_FUNCTION (current_function_decl)->language->other_ret_val + /* A structure used to gather together information about a statement group. We use this to gather related statements, for example the "then" part of a IF. In the case where it represents a lexical scope, we may also @@ -626,6 +636,7 @@ gigi (Node_Id gnat_root, int max_gnat_node, int number_name ATTRIBUTE_UNUSED, { begin_subprog_body (info->elab_proc); end_subprog_body (gnu_body); + rest_of_subprog_body_compilation (info->elab_proc); } } @@ -2502,9 +2513,275 @@ establish_gnat_vms_condition_handler (void) add_stmt (establish_stmt); } -/* Similar, but for RETURN_EXPR. If RET_VAL is non-null, build a RETURN_EXPR - around the assignment of RET_VAL to RET_OBJ. Otherwise just build a bare - RETURN_EXPR around RESULT_OBJ, which may be null in this case. */ +/* This page implements a form of Named Return Value optimization modelled + on the C++ optimization of the same name. The main difference is that + we disregard any semantical considerations when applying it here, the + counterpart being that we don't try to apply it to semantically loaded + return types, i.e. types with the TREE_ADDRESSABLE flag set. + + We consider a function body of the following GENERIC form: + + return_type R1; + [...] + RETURN_EXPR [<retval> = ...] + [...] + RETURN_EXPR [<retval> = R1] + [...] + return_type Ri; + [...] + RETURN_EXPR [<retval> = ...] + [...] + RETURN_EXPR [<retval> = Ri] + [...] + + and we try to fulfill a simple criterion that would make it possible to + replace one or several Ri variables with the RESULT_DECL of the function. + + The first observation is that RETURN_EXPRs that don't directly reference + any of the Ri variables on the RHS of their assignment are transparent wrt + the optimization. This is because the Ri variables aren't addressable so + any transformation applied to them doesn't affect the RHS; moreover, the + assignment writes the full <retval> object so existing values are entirely + discarded. + + This property can be extended to some forms of RETURN_EXPRs that reference + the Ri variables, for example CONSTRUCTORs, but isn't true in the general + case, in particular when function calls are involved. + + Therefore the algorithm is as follows: + + 1. Collect the list of candidates for a Named Return Value (Ri variables + on the RHS of assignments of RETURN_EXPRs) as well as the list of the + other expressions on the RHS of such assignments. + + 2. Prune the members of the first list (candidates) that are referenced + by a member of the second list (expressions). + + 3. Extract a set of candidates with non-overlapping live ranges from the + first list. These are the Named Return Values. + + 4. Adjust the relevant RETURN_EXPRs and replace the occurrences of the + Named Return Values in the function with the RESULT_DECL. */ + +struct nrv_data +{ + bitmap nrv; + tree result; + struct pointer_set_t *visited; +}; + +/* Return true if T is a Named Return Value. */ + +static inline bool +is_nrv_p (bitmap nrv, tree t) +{ + return TREE_CODE (t) == VAR_DECL && bitmap_bit_p (nrv, DECL_UID (t)); +} + +/* Helper function for walk_tree, used by finalize_nrv below. */ + +static tree +prune_nrv_r (tree *tp, int *walk_subtrees, void *data) +{ + struct nrv_data *dp = (struct nrv_data *)data; + tree t = *tp; + + /* No need to walk into types or decls. */ + if (IS_TYPE_OR_DECL_P (t)) + *walk_subtrees = 0; + + if (is_nrv_p (dp->nrv, t)) + bitmap_clear_bit (dp->nrv, DECL_UID (t)); + + return NULL_TREE; +} + +/* Prune Named Return Values in BLOCK and return true if there is still a + Named Return Value in BLOCK or one of its sub-blocks. */ + +static bool +prune_nrv_in_block (bitmap nrv, tree block) +{ + bool has_nrv = false; + tree t; + + /* First recurse on the sub-blocks. */ + for (t = BLOCK_SUBBLOCKS (block); t; t = BLOCK_CHAIN (t)) + has_nrv |= prune_nrv_in_block (nrv, t); + + /* Then make sure to keep at most one NRV per block. */ + for (t = BLOCK_VARS (block); t; t = DECL_CHAIN (t)) + if (is_nrv_p (nrv, t)) + { + if (has_nrv) + bitmap_clear_bit (nrv, DECL_UID (t)); + else + has_nrv = true; + } + + return has_nrv; +} + +/* Helper function for walk_tree, used by finalize_nrv below. */ + +static tree +finalize_nrv_r (tree *tp, int *walk_subtrees, void *data) +{ + struct nrv_data *dp = (struct nrv_data *)data; + tree t = *tp; + + /* No need to walk into types. */ + if (TYPE_P (t)) + *walk_subtrees = 0; + + /* Change RETURN_EXPRs of NRVs to just refer to the RESULT_DECL; this is a + nop, but differs from using NULL_TREE in that it indicates that we care + about the value of the RESULT_DECL. */ + else if (TREE_CODE (t) == RETURN_EXPR + && TREE_CODE (TREE_OPERAND (t, 0)) == MODIFY_EXPR) + { + tree ret_val = TREE_OPERAND (TREE_OPERAND (t, 0), 1), init_expr; + + /* If this is the temporary created for a return value with variable + size in call_to_gnu, we replace the RHS with the init expression. */ + if (TREE_CODE (ret_val) == COMPOUND_EXPR + && TREE_CODE (TREE_OPERAND (ret_val, 0)) == INIT_EXPR + && TREE_OPERAND (TREE_OPERAND (ret_val, 0), 0) + == TREE_OPERAND (ret_val, 1)) + { + init_expr = TREE_OPERAND (TREE_OPERAND (ret_val, 0), 1); + ret_val = TREE_OPERAND (ret_val, 1); + } + else + init_expr = NULL_TREE; + + /* Strip useless conversions around the return value. */ + if (gnat_useless_type_conversion (ret_val)) + ret_val = TREE_OPERAND (ret_val, 0); + + if (is_nrv_p (dp->nrv, ret_val)) + { + if (init_expr) + TREE_OPERAND (TREE_OPERAND (t, 0), 1) = init_expr; + else + TREE_OPERAND (t, 0) = dp->result; + } + } + + /* Replace the DECL_EXPR of NRVs with an initialization of the RESULT_DECL, + if needed. */ + else if (TREE_CODE (t) == DECL_EXPR + && is_nrv_p (dp->nrv, DECL_EXPR_DECL (t))) + { + tree var = DECL_EXPR_DECL (t), init; + + if (DECL_INITIAL (var)) + { + init = build_binary_op (INIT_EXPR, NULL_TREE, dp->result, + DECL_INITIAL (var)); + SET_EXPR_LOCATION (init, EXPR_LOCATION (t)); + DECL_INITIAL (var) = NULL_TREE; + } + else + init = build_empty_stmt (EXPR_LOCATION (t)); + *tp = init; + + /* Identify the NRV to the RESULT_DECL for debugging purposes. */ + SET_DECL_VALUE_EXPR (var, dp->result); + DECL_HAS_VALUE_EXPR_P (var) = 1; + /* ??? Kludge to avoid an assertion failure during inlining. */ + DECL_SIZE (var) = bitsize_unit_node; + DECL_SIZE_UNIT (var) = size_one_node; + } + + /* And replace all uses of NRVs with the RESULT_DECL. */ + else if (is_nrv_p (dp->nrv, t)) + *tp = convert (TREE_TYPE (t), dp->result); + + /* Avoid walking into the same tree more than once. Unfortunately, we + can't just use walk_tree_without_duplicates because it would only call + us for the first occurrence of NRVs in the function body. */ + if (pointer_set_insert (dp->visited, *tp)) + *walk_subtrees = 0; + + return NULL_TREE; +} + +/* Finalize the Named Return Value optimization for FNDECL. The NRV bitmap + contains the candidates for Named Return Value and OTHER is a list of + the other return values. */ + +static void +finalize_nrv (tree fndecl, bitmap nrv, VEC(tree,gc) *other) +{ + struct cgraph_node *node; + struct nrv_data data; + unsigned int i; + tree iter; + + /* We shouldn't be applying the optimization to return types that we aren't + allowed to manipulate freely. */ + gcc_assert (!TREE_ADDRESSABLE (TREE_TYPE (TREE_TYPE (fndecl)))); + + /* Prune the candidates that are referenced by other return values. */ + data.nrv = nrv; + data.result = NULL_TREE; + data.visited = NULL; + for (i = 0; VEC_iterate(tree, other, i, iter); i++) + walk_tree_without_duplicates (&iter, prune_nrv_r, &data); + if (bitmap_empty_p (nrv)) + return; + + /* Prune also the candidates that are referenced by nested functions. */ + node = cgraph_get_create_node (fndecl); + for (node = node->nested; node; node = node->next_nested) + walk_tree_without_duplicates (&DECL_SAVED_TREE (node->decl), prune_nrv_r, + &data); + if (bitmap_empty_p (nrv)) + return; + + /* Extract a set of NRVs with non-overlapping live ranges. */ + if (!prune_nrv_in_block (nrv, DECL_INITIAL (fndecl))) + return; + + /* Adjust the relevant RETURN_EXPRs and replace the occurrences of NRVs. */ + data.nrv = nrv; + data.result = DECL_RESULT (fndecl); + data.visited = pointer_set_create (); + walk_tree (&DECL_SAVED_TREE (fndecl), finalize_nrv_r, &data, NULL); + pointer_set_destroy (data.visited); +} + +/* Return true if RET_VAL can be used as a Named Return Value for the + anonymous return object RET_OBJ. */ + +static bool +return_value_ok_for_nrv_p (tree ret_obj, tree ret_val) +{ + if (TREE_CODE (ret_val) != VAR_DECL) + return false; + + if (TREE_THIS_VOLATILE (ret_val)) + return false; + + if (DECL_CONTEXT (ret_val) != current_function_decl) + return false; + + if (TREE_STATIC (ret_val)) + return false; + + if (TREE_ADDRESSABLE (ret_val)) + return false; + + if (DECL_ALIGN (ret_val) > DECL_ALIGN (ret_obj)) + return false; + + return true; +} + +/* Build a RETURN_EXPR. If RET_VAL is non-null, build a RETURN_EXPR around + the assignment of RET_VAL to RET_OBJ. Otherwise build a bare RETURN_EXPR + around RESULT_OBJ, which may be null in this case. */ static tree build_return_expr (tree ret_obj, tree ret_val) @@ -2533,6 +2810,41 @@ build_return_expr (tree ret_obj, tree ret_val) ret_val = convert (operation_type, ret_val); result_expr = build2 (MODIFY_EXPR, void_type_node, ret_obj, ret_val); + + /* If the function returns an aggregate type, find out whether this is + a candidate for Named Return Value. If so, record it. Otherwise, + if this is an expression of some kind, record it elsewhere. */ + if (optimize + && AGGREGATE_TYPE_P (operation_type) + && !TYPE_IS_FAT_POINTER_P (operation_type) + && aggregate_value_p (operation_type, current_function_decl)) + { + /* Recognize the temporary created for a return value with variable + size in call_to_gnu. We want to eliminate it if possible. */ + if (TREE_CODE (ret_val) == COMPOUND_EXPR + && TREE_CODE (TREE_OPERAND (ret_val, 0)) == INIT_EXPR + && TREE_OPERAND (TREE_OPERAND (ret_val, 0), 0) + == TREE_OPERAND (ret_val, 1)) + ret_val = TREE_OPERAND (ret_val, 1); + + /* Strip useless conversions around the return value. */ + if (gnat_useless_type_conversion (ret_val)) + ret_val = TREE_OPERAND (ret_val, 0); + + /* Now apply the test to the return value. */ + if (return_value_ok_for_nrv_p (ret_obj, ret_val)) + { + if (!f_named_ret_val) + f_named_ret_val = BITMAP_GGC_ALLOC (); + bitmap_set_bit (f_named_ret_val, DECL_UID (ret_val)); + } + + /* Note that we need not care about CONSTRUCTORs here, as they are + totally transparent given the read-compose-write semantics of + assignments from CONSTRUCTORs. */ + else if (EXPR_P (ret_val)) + VEC_safe_push (tree, gc, f_other_ret_val, ret_val); + } } else result_expr = ret_obj; @@ -2601,6 +2913,7 @@ build_function_stub (tree gnu_subprog, Entity_Id gnat_subprog) gnat_poplevel (); end_subprog_body (end_stmt_group ()); + rest_of_subprog_body_compilation (gnu_stub_decl); } /* Subroutine of gnat_to_gnu to process gnat_node, an N_Subprogram_Body. We @@ -2855,6 +3168,18 @@ Subprogram_Body_to_gnu (Node_Id gnat_node) if (gnu_return_var_elmt) TREE_VALUE (gnu_return_var_elmt) = void_type_node; + /* If the function returns an aggregate type and we have candidates for + a Named Return Value, finalize the optimization. */ + if (optimize && gnu_subprog_language->named_ret_val) + { + finalize_nrv (gnu_subprog_decl, gnu_subprog_language->named_ret_val, + gnu_subprog_language->other_ret_val); + gnu_subprog_language->named_ret_val = NULL; + gnu_subprog_language->other_ret_val = NULL; + } + + rest_of_subprog_body_compilation (gnu_subprog_decl); + /* If there is a stub associated with the function, build it now. */ if (DECL_FUNCTION_STUB (gnu_subprog_decl)) build_function_stub (gnu_subprog_decl, gnat_subprog_id); @@ -3518,10 +3843,16 @@ call_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, tree gnu_target) else return gnu_call; - /* If we nevertheless need a value, make a COMPOUND_EXPR to return it. */ + /* If we nevertheless need a value, make a COMPOUND_EXPR to return it. + But first simplify if we have only one statement in the list. */ if (returning_value) - gnu_result - = build_compound_expr (TREE_TYPE (gnu_call), gnu_result, gnu_call); + { + tree first = expr_first (gnu_result), last = expr_last (gnu_result); + if (first == last) + gnu_result = first; + gnu_result + = build_compound_expr (TREE_TYPE (gnu_call), gnu_result, gnu_call); + } return gnu_result; } diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c index feae636dece..ca3218fd079 100644 --- a/gcc/ada/gcc-interface/utils.c +++ b/gcc/ada/gcc-interface/utils.c @@ -200,6 +200,9 @@ static GTY(()) struct gnat_binding_level *current_binding_level; /* A chain of gnat_binding_level structures awaiting reuse. */ static GTY((deletable)) struct gnat_binding_level *free_binding_level; +/* The context to be used for global declarations. */ +static GTY(()) tree global_context; + /* An array of global declarations. */ static GTY(()) VEC(tree,gc) *global_decls; @@ -497,15 +500,19 @@ gnat_zaplevel (void) free_binding_level = level; } -/* Records a ..._DECL node DECL as belonging to the current lexical scope - and uses GNAT_NODE for location information and propagating flags. */ +/* Record DECL as belonging to the current lexical scope and use GNAT_NODE + for location information and flag propagation. */ void gnat_pushdecl (tree decl, Node_Id gnat_node) { - /* If this decl is public external or at toplevel, there is no context. */ + /* If DECL is public external or at top level, it has global context. */ if ((TREE_PUBLIC (decl) && DECL_EXTERNAL (decl)) || global_bindings_p ()) - DECL_CONTEXT (decl) = 0; + { + if (!global_context) + global_context = build_translation_unit_decl (NULL_TREE); + DECL_CONTEXT (decl) = global_context; + } else { DECL_CONTEXT (decl) = current_function_decl; @@ -518,11 +525,12 @@ gnat_pushdecl (tree decl, Node_Id gnat_node) DECL_STATIC_CHAIN (decl) = 1; } - TREE_NO_WARNING (decl) = (gnat_node == Empty || Warnings_Off (gnat_node)); + TREE_NO_WARNING (decl) = (No (gnat_node) || Warnings_Off (gnat_node)); /* Set the location of DECL and emit a declaration for it. */ if (Present (gnat_node)) Sloc_to_locus (Sloc (gnat_node), &DECL_SOURCE_LOCATION (decl)); + add_decl_expr (decl, gnat_node); /* Put the declaration on the list. The list of declarations is in reverse @@ -1958,7 +1966,7 @@ begin_subprog_body (tree subprog_decl) make_decl_rtl (subprog_decl); } -/* Finish the definition of the current subprogram BODY and finalize it. */ +/* Finish translating the current subprogram and set its BODY. */ void end_subprog_body (tree body) @@ -1982,8 +1990,14 @@ end_subprog_body (tree body) DECL_SAVED_TREE (fndecl) = body; - current_function_decl = DECL_CONTEXT (fndecl); + current_function_decl = decl_function_context (fndecl); +} +/* Wrap up compilation of SUBPROG_DECL, a subprogram body. */ + +void +rest_of_subprog_body_compilation (tree subprog_decl) +{ /* We cannot track the location of errors past this point. */ error_gnat_node = Empty; @@ -1992,15 +2006,15 @@ end_subprog_body (tree body) return; /* Dump functions before gimplification. */ - dump_function (TDI_original, fndecl); + dump_function (TDI_original, subprog_decl); /* ??? This special handling of nested functions is probably obsolete. */ - if (!DECL_CONTEXT (fndecl)) - cgraph_finalize_function (fndecl, false); + if (!decl_function_context (subprog_decl)) + cgraph_finalize_function (subprog_decl, false); else /* Register this function with cgraph just far enough to get it added to our parent's nested function list. */ - (void) cgraph_get_create_node (fndecl); + (void) cgraph_get_create_node (subprog_decl); } tree @@ -2194,6 +2208,20 @@ gnat_types_compatible_p (tree t1, tree t2) return 0; } +/* Return true if EXPR is a useless type conversion. */ + +bool +gnat_useless_type_conversion (tree expr) +{ + if (CONVERT_EXPR_P (expr) + || TREE_CODE (expr) == VIEW_CONVERT_EXPR + || TREE_CODE (expr) == NON_LVALUE_EXPR) + return gnat_types_compatible_p (TREE_TYPE (expr), + TREE_TYPE (TREE_OPERAND (expr, 0))); + + return false; +} + /* Return true if T, a FUNCTION_TYPE, has the specified list of flags. */ bool diff --git a/gcc/ada/opt.ads b/gcc/ada/opt.ads index 65a2d17b8e0..ed940d43c19 100644 --- a/gcc/ada/opt.ads +++ b/gcc/ada/opt.ads @@ -1638,11 +1638,11 @@ package Opt is -- GNAT -- This is the value of the configuration switch for the Ada 83 mode, as -- set by the command line switches -gnat83/95/05, and possibly modified by - -- the use of configuration pragmas Ada_83/Ada95/Ada05. This switch is used - -- to set the initial value for Ada_Version mode at the start of analysis - -- of a unit. Note however, that the setting of this flag is ignored for - -- internal and predefined units (which are always compiled in the most up - -- to date version of Ada). + -- the use of configuration pragmas Ada_*. This switch is used to set the + -- initial value for Ada_Version mode at the start of analysis of a unit. + -- Note however that the setting of this flag is ignored for internal and + -- predefined units (which are always compiled in the most up to date + -- version of Ada). Ada_Version_Explicit_Config : Ada_Version_Type; -- GNAT diff --git a/gcc/ada/par-ch12.adb b/gcc/ada/par-ch12.adb index b8b760cce4e..06261bc60b3 100644 --- a/gcc/ada/par-ch12.adb +++ b/gcc/ada/par-ch12.adb @@ -336,7 +336,7 @@ package body Ch12 is begin Generic_Assoc_Node := New_Node (N_Generic_Association, Token_Ptr); - -- Ada2005: an association can be given by: others => <> + -- Ada 2005: an association can be given by: others => <> if Token = Tok_Others then if Ada_Version < Ada_2005 then diff --git a/gcc/ada/par-ch2.adb b/gcc/ada/par-ch2.adb index 67d52f67907..02914422c2c 100644 --- a/gcc/ada/par-ch2.adb +++ b/gcc/ada/par-ch2.adb @@ -59,10 +59,14 @@ package body Ch2 is begin -- All set if we do indeed have an identifier + -- Code duplication, see Par_Ch3.P_Defining_Identifier??? + if Token = Tok_Identifier then - -- Ada 2005 (AI-284): Compiling in Ada95 mode we warn that INTERFACE, - -- OVERRIDING, and SYNCHRONIZED are new reserved words. + -- Shouldn't the warnings below be emitted when in Ada 83 mode??? + + -- Ada 2005 (AI-284): If compiling in Ada 95 mode, we warn that + -- INTERFACE, OVERRIDING, and SYNCHRONIZED are new reserved words. if Ada_Version = Ada_95 and then Warn_On_Ada_2005_Compatibility diff --git a/gcc/ada/par-ch3.adb b/gcc/ada/par-ch3.adb index d58bce10451..c05a5b65b49 100644 --- a/gcc/ada/par-ch3.adb +++ b/gcc/ada/par-ch3.adb @@ -210,12 +210,19 @@ package body Ch3 is -- we set Force_Msg to True, since we want at least one message for each -- separate declaration (but not use) of a reserved identifier. + -- Duplication should be removed, common code should be factored??? + if Token = Tok_Identifier then - -- Ada 2005 (AI-284): Compiling in Ada95 mode we warn that INTERFACE, - -- OVERRIDING, and SYNCHRONIZED are new reserved words. Note that - -- in the case where these keywords are misused in Ada 95 mode, - -- this routine will generally not be called at all. + -- Shouldn't the warnings below be emitted when in Ada 83 mode??? + + -- Ada 2005 (AI-284): If compiling in Ada 95 mode, we warn that + -- INTERFACE, OVERRIDING, and SYNCHRONIZED are new reserved words. + -- Note that in the case where these keywords are misused in Ada 95 + -- mode, this routine will generally not be called at all. + + -- What sort of misuse is this comment talking about??? These are + -- perfectly legitimate defining identifiers in Ada 95??? if Ada_Version = Ada_95 and then Warn_On_Ada_2005_Compatibility @@ -657,7 +664,7 @@ package body Ch3 is Error_Msg_SP ("(Ada 83) limited record declaration not allowed!"); - -- In Ada2005, "abstract limited" can appear before "new", + -- In Ada 2005, "abstract limited" can appear before "new", -- but it cannot be part of an untagged record declaration. elsif Abstract_Present @@ -4236,7 +4243,7 @@ package body Ch3 is P_Identifier_Declarations (Decls, Done, In_Spec); end if; - -- Ada2005: A subprogram declaration can start with "not" or + -- Ada 2005: A subprogram declaration can start with "not" or -- "overriding". In older versions, "overriding" is handled -- like an identifier, with the appropriate messages. diff --git a/gcc/ada/par-ch5.adb b/gcc/ada/par-ch5.adb index fcfb428d1f8..e86f01c9155 100644 --- a/gcc/ada/par-ch5.adb +++ b/gcc/ada/par-ch5.adb @@ -1649,7 +1649,7 @@ package body Ch5 is if Token = Tok_Of or else Token = Tok_Colon then if Ada_Version < Ada_2012 then - Error_Msg_SC ("iterator is an Ada2012 feature"); + Error_Msg_SC ("iterator is an Ada 2012 feature"); end if; return P_Iterator_Specification (ID_Node); diff --git a/gcc/ada/par-ch6.adb b/gcc/ada/par-ch6.adb index 7b200e761b2..7a9df3ac804 100644 --- a/gcc/ada/par-ch6.adb +++ b/gcc/ada/par-ch6.adb @@ -184,7 +184,7 @@ package body Ch6 is Scope.Table (Scope.Last).Ecol := Start_Column; Scope.Table (Scope.Last).Lreq := False; - -- Ada2005: scan leading NOT OVERRIDING indicator + -- Ada 2005: scan leading NOT OVERRIDING indicator if Token = Tok_Not then Scan; -- past NOT @@ -1341,7 +1341,7 @@ package body Ch6 is if Token = Tok_Aliased then if Ada_Version < Ada_2012 then - Error_Msg_SC ("ALIASED parameter is an Ada2012 feature"); + Error_Msg_SC ("ALIASED parameter is an Ada 2012 feature"); else Set_Aliased_Present (Specification_Node); end if; diff --git a/gcc/ada/s-osinte-freebsd.ads b/gcc/ada/s-osinte-freebsd.ads index d3d5c8763e4..cbd2a2df428 100644 --- a/gcc/ada/s-osinte-freebsd.ads +++ b/gcc/ada/s-osinte-freebsd.ads @@ -645,7 +645,10 @@ private type clockid_t is new int; CLOCK_REALTIME : constant clockid_t := 0; - CLOCK_MONOTONIC : constant clockid_t := 4; + CLOCK_MONOTONIC : constant clockid_t := 0; + -- On FreeBSD, pthread_cond_timedwait assumes a CLOCK_REALTIME time by + -- default (unless pthread_condattr_setclock is used to set an alternate + -- clock). type pthread_t is new System.Address; type pthread_attr_t is new System.Address; diff --git a/gcc/ada/s-regpat.adb b/gcc/ada/s-regpat.adb index 53218978a0b..ac938be9114 100755 --- a/gcc/ada/s-regpat.adb +++ b/gcc/ada/s-regpat.adb @@ -7,7 +7,7 @@ -- B o d y -- -- -- -- Copyright (C) 1986 by University of Toronto. -- --- Copyright (C) 1999-2010, AdaCore -- +-- Copyright (C) 1999-2011, 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- -- @@ -2017,7 +2017,7 @@ package body System.Regpat is (Dummy.Program'First .. Dummy.Program'First + Size - 1)); else -- We have to recompile now that we know the size - -- ??? Can we use Ada05's return construct ? + -- ??? Can we use Ada 05's return construct ? declare Result : Pattern_Matcher (Size); begin diff --git a/gcc/ada/s-tpopde-vms.ads b/gcc/ada/s-tpopde-vms.ads index aadafa6490b..e690f306e7a 100644 --- a/gcc/ada/s-tpopde-vms.ads +++ b/gcc/ada/s-tpopde-vms.ads @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 2000-2009, Free Software Foundation, Inc. -- +-- Copyright (C) 2000-2011, Free Software Foundation, Inc. -- -- -- -- GNARL 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- -- @@ -36,7 +36,7 @@ package System.Task_Primitives.Operations.DEC is procedure Interrupt_AST_Handler (ID : Address); pragma Convention (C, Interrupt_AST_Handler); - -- Handles the AST for Ada95 Interrupts + -- Handles the AST for Ada 95 Interrupts procedure RMS_AST_Handler (ID : Address); -- Handles the AST for RMS_Asynch_Operations diff --git a/gcc/ada/sem_aggr.adb b/gcc/ada/sem_aggr.adb index 657ece339b1..f4d2ad8a0a5 100644 --- a/gcc/ada/sem_aggr.adb +++ b/gcc/ada/sem_aggr.adb @@ -3414,7 +3414,7 @@ package body Sem_Aggr is Selector_Name); return; - -- (Ada2005): If this is an association with a box, + -- (Ada 2005): If this is an association with a box, -- indicate that the association need not represent -- any component. diff --git a/gcc/ada/sem_attr.adb b/gcc/ada/sem_attr.adb index 738edda77fd..caacc45c4d2 100644 --- a/gcc/ada/sem_attr.adb +++ b/gcc/ada/sem_attr.adb @@ -2125,7 +2125,7 @@ package body Sem_Attr is case Attr_Id is - -- Attributes related to Ada2012 iterators. Attribute specifications + -- Attributes related to Ada 2012 iterators. Attribute specifications -- exist for these, but they cannot be queried. when Attribute_Constant_Indexing | @@ -6120,7 +6120,7 @@ package body Sem_Attr is case Id is - -- Attributes related to Ada2012 iterators (placeholder ???) + -- Attributes related to Ada 2012 iterators (placeholder ???) when Attribute_Constant_Indexing => null; when Attribute_Default_Iterator => null; diff --git a/gcc/ada/sem_cat.adb b/gcc/ada/sem_cat.adb index 58aaee1d573..04cf958ca92 100644 --- a/gcc/ada/sem_cat.adb +++ b/gcc/ada/sem_cat.adb @@ -900,7 +900,7 @@ package body Sem_Cat is -- If the type is private, it must have the Ada 2005 pragma -- Has_Preelaborable_Initialization. -- The check is omitted within predefined units. This is probably - -- obsolete code to fix the Ada95 weakness in this area ??? + -- obsolete code to fix the Ada 95 weakness in this area ??? if Is_Private_Type (T) and then not Has_Pragma_Preelab_Init (T) diff --git a/gcc/ada/sem_ch10.adb b/gcc/ada/sem_ch10.adb index c6f18da4e54..17fe12137e3 100644 --- a/gcc/ada/sem_ch10.adb +++ b/gcc/ada/sem_ch10.adb @@ -208,7 +208,7 @@ package body Sem_Ch10 is -- Limited_With_Clauses -- -------------------------- - -- Limited_With clauses are the mechanism chosen for Ada05 to support + -- Limited_With clauses are the mechanism chosen for Ada 05 to support -- mutually recursive types declared in different units. A limited_with -- clause that names package P in the context of unit U makes the types -- declared in the visible part of P available within U, but with the diff --git a/gcc/ada/sem_ch12.adb b/gcc/ada/sem_ch12.adb index dbf3896bdb3..6dd6e7b5589 100644 --- a/gcc/ada/sem_ch12.adb +++ b/gcc/ada/sem_ch12.adb @@ -258,7 +258,7 @@ package body Sem_Ch12 is -- are not accessible outside of the instance. -- In a generic, a formal package is treated like a special instantiation. - -- Our Ada95 compiler handled formals with and without box in different + -- Our Ada 95 compiler handled formals with and without box in different -- ways. With partial parametrization, we use a single model for both. -- We create a package declaration that consists of the specification of -- the generic package, and a set of declarations that map the actuals diff --git a/gcc/ada/sem_ch3.adb b/gcc/ada/sem_ch3.adb index dd48cff4d17..fe4488b483e 100644 --- a/gcc/ada/sem_ch3.adb +++ b/gcc/ada/sem_ch3.adb @@ -9026,7 +9026,7 @@ package body Sem_Ch3 is -- The partial view of T may have been a private extension, for -- which inherited functions dispatching on result are abstract. -- If the full view is a null extension, there is no need for - -- overriding in Ada2005, but wrappers need to be built for them + -- overriding in Ada 2005, but wrappers need to be built for them -- (see exp_ch3, Build_Controlling_Function_Wrappers). if Is_Null_Extension (T) @@ -18287,7 +18287,7 @@ package body Sem_Ch3 is -- Look up tree to find an appropriate insertion point. We -- can't just use insert_actions because later processing - -- depends on the insertion node. Prior to Ada2012 the + -- depends on the insertion node. Prior to Ada 2012 the -- insertion point could only be a declaration or a loop, but -- quantified expressions can appear within any context in an -- expression, and the insertion point can be any statement, diff --git a/gcc/ada/sem_ch4.adb b/gcc/ada/sem_ch4.adb index 742e1c9afae..7f54ba517d6 100644 --- a/gcc/ada/sem_ch4.adb +++ b/gcc/ada/sem_ch4.adb @@ -3434,7 +3434,7 @@ package body Sem_Ch4 is -- of the high bound. procedure Check_Universal_Expression (N : Node_Id); - -- In Ada83, reject bounds of a universal range that are not + -- In Ada 83, reject bounds of a universal range that are not -- literals or entity names. ----------------------- diff --git a/gcc/ada/sem_ch5.adb b/gcc/ada/sem_ch5.adb index 875eb1c0778..1b0f919d3ff 100644 --- a/gcc/ada/sem_ch5.adb +++ b/gcc/ada/sem_ch5.adb @@ -2068,7 +2068,7 @@ package body Sem_Ch5 is Set_Parent (D_Copy, Parent (DS)); Pre_Analyze_Range (D_Copy); - -- Ada2012: If the domain of iteration is a function call, + -- Ada 2012: If the domain of iteration is a function call, -- it is the new iterator form. -- We have also implemented the shorter form : for X in S diff --git a/gcc/ada/sem_ch6.adb b/gcc/ada/sem_ch6.adb index a9a45bc6445..2fc3b96670d 100644 --- a/gcc/ada/sem_ch6.adb +++ b/gcc/ada/sem_ch6.adb @@ -387,7 +387,7 @@ package body Sem_Ch6 is begin Analyze (P); - -- A call of the form A.B (X) may be an Ada05 call, which is rewritten + -- A call of the form A.B (X) may be an Ada 05 call, which is rewritten -- as B (A, X). If the rewriting is successful, the call has been -- analyzed and we just return. @@ -452,7 +452,18 @@ package body Sem_Ch6 is -- incompatibility with Ada 95. Not clear whether this should be -- enforced yet or perhaps controllable with special switch. ??? - if Is_Limited_Type (R_Type) + -- A limited interface that is not immutably limited is OK. + + if Is_Limited_Interface (R_Type) + and then + not (Is_Task_Interface (R_Type) + or else Is_Protected_Interface (R_Type) + or else Is_Synchronized_Interface (R_Type)) + then + null; + + elsif Is_Limited_Type (R_Type) + and then not Is_Interface (R_Type) and then Comes_From_Source (N) and then not In_Instance_Body and then not OK_For_Limited_Init_In_05 (R_Type, Expr) @@ -484,7 +495,7 @@ package body Sem_Ch6 is elsif Warn_On_Ada_2005_Compatibility or GNAT_Mode then if Inside_A_Generic then Error_Msg_N - ("return of limited object not permitted in Ada2005 " + ("return of limited object not permitted in Ada 2005 " & "(RM-2005 6.5(5.5/2))?", Expr); elsif Is_Immutably_Limited_Type (R_Type) then @@ -2370,7 +2381,7 @@ package body Sem_Ch6 is -- expansion has generated an equivalent type that is used when -- elaborating the body. - -- An exception in the case of Ada2012, AI05-177: The bodies + -- An exception in the case of Ada 2012, AI05-177: The bodies -- created for expression functions do not freeze. if No (Spec_Id) @@ -6123,7 +6134,7 @@ package body Sem_Ch6 is Desig_2 : Entity_Id; begin - -- In Ada2005, access constant indicators must match for + -- In Ada 2005, access constant indicators must match for -- subtype conformance. if Ada_Version >= Ada_2005 @@ -8714,7 +8725,7 @@ package body Sem_Ch6 is -- inherited in a derivation, or when an inherited operation -- of a tagged full type overrides the inherited operation of -- a private extension. Ada 83 had a special rule for the - -- literal case. In Ada95, the later implicit operation hides + -- literal case. In Ada 95, the later implicit operation hides -- the former, and the literal is always the former. In the -- odd case where both are derived operations declared at the -- same point, both operations should be declared, and in that @@ -10251,7 +10262,7 @@ package body Sem_Ch6 is if Nkind (Parameter_Type (Spec)) = N_Access_Definition then - -- Ada 2005 (AI-231): In Ada95, access parameters are always non- + -- Ada 2005 (AI-231): In Ada 95, access parameters are always non- -- null; In Ada 2005, only if then null_exclusion is explicit. if Ada_Version < Ada_2005 diff --git a/gcc/ada/sem_intr.adb b/gcc/ada/sem_intr.adb index 9203a9af878..19016822a3a 100644 --- a/gcc/ada/sem_intr.adb +++ b/gcc/ada/sem_intr.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 1992-2010, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2011, 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- -- @@ -124,7 +124,7 @@ package body Sem_Intr is end if; -- For Import_xxx calls, argument must be static string. A string - -- literal is legal even in Ada83 mode, where such literals are + -- literal is legal even in Ada 83 mode, where such literals are -- not static. if Cnam = Name_Import_Address diff --git a/gcc/ada/sem_res.adb b/gcc/ada/sem_res.adb index 9ce5282d5b8..7f10c266225 100644 --- a/gcc/ada/sem_res.adb +++ b/gcc/ada/sem_res.adb @@ -64,6 +64,7 @@ with Sem_Elab; use Sem_Elab; with Sem_Eval; use Sem_Eval; with Sem_Intr; use Sem_Intr; with Sem_Util; use Sem_Util; +with Targparm; use Targparm; with Sem_Type; use Sem_Type; with Sem_Warn; use Sem_Warn; with Sinfo; use Sinfo; @@ -4874,13 +4875,33 @@ package body Sem_Res is (Is_Real_Type (Etype (Rop)) and then Expr_Value_R (Rop) = Ureal_0)) then - -- Specialize the warning message according to the operation + -- Specialize the warning message according to the operation. + -- The following warnings are for the case case Nkind (N) is when N_Op_Divide => - Apply_Compile_Time_Constraint_Error - (N, "division by zero?", CE_Divide_By_Zero, - Loc => Sloc (Right_Opnd (N))); + + -- For division, we have two cases, for float division + -- of an unconstrained float type, on a machine where + -- Machine_Overflows is false, we don't get an exception + -- at run-time, but rather an infinity or Nan. The Nan + -- case is pretty obscure, so just warn about infinities. + + if Is_Floating_Point_Type (Typ) + and then not Is_Constrained (Typ) + and then not Machine_Overflows_On_Target + then + Error_Msg_N + ("float division by zero, " & + "may generate '+'/'- infinity?", Right_Opnd (N)); + + -- For all other cases, we get a Constraint_Error + + else + Apply_Compile_Time_Constraint_Error + (N, "division by zero?", CE_Divide_By_Zero, + Loc => Sloc (Right_Opnd (N))); + end if; when N_Op_Rem => Apply_Compile_Time_Constraint_Error diff --git a/gcc/ada/sem_res.ads b/gcc/ada/sem_res.ads index 361b8651569..42b819186dc 100644 --- a/gcc/ada/sem_res.ads +++ b/gcc/ada/sem_res.ads @@ -95,8 +95,8 @@ package Sem_Res is procedure Ambiguous_Character (C : Node_Id); -- Give list of candidate interpretations when a character literal cannot -- be resolved, for example in a (useless) comparison such as 'A' = 'B'. - -- In Ada95 the literals in question can be of type Character or Wide_ - -- Character. In Ada2005 Wide_Wide_Character is also a candidate. The + -- In Ada 95 the literals in question can be of type Character or Wide_ + -- Character. In Ada 2005 Wide_Wide_Character is also a candidate. The -- node may also be overloaded with user-defined character types. procedure Check_Parameterless_Call (N : Node_Id); diff --git a/gcc/ada/sem_type.adb b/gcc/ada/sem_type.adb index 8c2eeeef65b..067a2d4f853 100644 --- a/gcc/ada/sem_type.adb +++ b/gcc/ada/sem_type.adb @@ -1988,11 +1988,11 @@ package body Sem_Type is -- Otherwise, the predefined operator has precedence, or if the user- -- defined operation is directly visible we have a true ambiguity. - -- If this is a fixed-point multiplication and division in Ada83 mode, + -- If this is a fixed-point multiplication and division in Ada 83 mode, -- exclude the universal_fixed operator, which often causes ambiguities -- in legacy code. - -- Ditto in Ada2012, where an ambiguity may arise for an operation on + -- Ditto in Ada 2012, where an ambiguity may arise for an operation on -- a partial view that is completed with a fixed point type. See -- AI05-0020 and AI05-0209. The ambiguity is resolved in favor of the -- user-defined subprogram so that a client of the package has the diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb index 5df84dcf7d7..1881563aa88 100644 --- a/gcc/ada/sem_util.adb +++ b/gcc/ada/sem_util.adb @@ -2993,7 +2993,7 @@ package body Sem_Util is if not Is_Local_Anonymous_Access (Etype (Expr)) then -- Handle type conversions introduced for a rename of an - -- Ada2012 stand-alone object of an anonymous access type. + -- Ada 2012 stand-alone object of an anonymous access type. return Dynamic_Accessibility_Level (Expression (Expr)); end if; @@ -7501,7 +7501,7 @@ package body Sem_Util is Is_Object_Reference (Prefix (N)) or else Is_Access_Type (Etype (Prefix (N))); - -- In Ada95, a function call is a constant object; a procedure + -- In Ada 95, a function call is a constant object; a procedure -- call is not. when N_Function_Call => @@ -7617,7 +7617,7 @@ package body Sem_Util is elsif Original_Node (AV) /= AV then - -- In Ada2012, the explicit dereference may be a rewritten call to a + -- In Ada 2012, the explicit dereference may be a rewritten call to a -- Reference function. if Ada_Version >= Ada_2012 diff --git a/gcc/builtins.c b/gcc/builtins.c index 3055927f369..bf1766a56a6 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -4516,20 +4516,33 @@ expand_builtin_alloca (tree exp, bool cannot_accumulate) { rtx op0; rtx result; + bool valid_arglist; + unsigned int align; + bool alloca_with_align = (DECL_FUNCTION_CODE (get_callee_fndecl (exp)) + == BUILT_IN_ALLOCA_WITH_ALIGN); /* Emit normal call if marked not-inlineable. */ if (CALL_CANNOT_INLINE_P (exp)) return NULL_RTX; - if (!validate_arglist (exp, INTEGER_TYPE, VOID_TYPE)) + valid_arglist + = (alloca_with_align + ? validate_arglist (exp, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE) + : validate_arglist (exp, INTEGER_TYPE, VOID_TYPE)); + + if (!valid_arglist) return NULL_RTX; /* Compute the argument. */ op0 = expand_normal (CALL_EXPR_ARG (exp, 0)); + /* Compute the alignment. */ + align = (alloca_with_align + ? TREE_INT_CST_LOW (CALL_EXPR_ARG (exp, 1)) + : BIGGEST_ALIGNMENT); + /* Allocate the desired space. */ - result = allocate_dynamic_stack_space (op0, 0, BIGGEST_ALIGNMENT, - cannot_accumulate); + result = allocate_dynamic_stack_space (op0, 0, align, cannot_accumulate); result = convert_memory_address (ptr_mode, result); return result; @@ -5304,6 +5317,7 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode, && !called_as_built_in (fndecl) && DECL_ASSEMBLER_NAME_SET_P (fndecl) && fcode != BUILT_IN_ALLOCA + && fcode != BUILT_IN_ALLOCA_WITH_ALIGN && fcode != BUILT_IN_FREE) return expand_call (exp, target, ignore); @@ -5559,6 +5573,7 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode, return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0); case BUILT_IN_ALLOCA: + case BUILT_IN_ALLOCA_WITH_ALIGN: /* If the allocation stems from the declaration of a variable-sized object, it cannot accumulate. */ target = expand_builtin_alloca (exp, CALL_ALLOCA_FOR_VAR_P (exp)); @@ -10360,7 +10375,7 @@ fold_builtin_varargs (location_t loc, tree fndecl, tree exp, been inlined, otherwise e.g. -D_FORTIFY_SOURCE checking might not be performed. */ -static bool +bool avoid_folding_inline_builtin (tree fndecl) { return (DECL_DECLARED_INLINE_P (fndecl) @@ -13568,6 +13583,7 @@ is_inexpensive_builtin (tree decl) { case BUILT_IN_ABS: case BUILT_IN_ALLOCA: + case BUILT_IN_ALLOCA_WITH_ALIGN: case BUILT_IN_BSWAP32: case BUILT_IN_BSWAP64: case BUILT_IN_CLZ: diff --git a/gcc/builtins.def b/gcc/builtins.def index 424f0f1a085..59c082de983 100644 --- a/gcc/builtins.def +++ b/gcc/builtins.def @@ -738,6 +738,7 @@ DEF_BUILTIN_STUB (BUILT_IN_SETJMP_RECEIVER, "__builtin_setjmp_receiver") /* Implementing variable sized local variables. */ DEF_BUILTIN_STUB (BUILT_IN_STACK_SAVE, "__builtin_stack_save") DEF_BUILTIN_STUB (BUILT_IN_STACK_RESTORE, "__builtin_stack_restore") +DEF_BUILTIN_STUB (BUILT_IN_ALLOCA_WITH_ALIGN, "__builtin_alloca_with_align") /* Object size checking builtins. */ DEF_GCC_BUILTIN (BUILT_IN_OBJECT_SIZE, "object_size", BT_FN_SIZE_CONST_PTR_INT, ATTR_PURE_NOTHROW_LEAF_LIST) diff --git a/gcc/c-parser.c b/gcc/c-parser.c index a1ed48d576f..c948b802ca5 100644 --- a/gcc/c-parser.c +++ b/gcc/c-parser.c @@ -5990,7 +5990,7 @@ c_parser_alignof_expression (c_parser *parser) } /* Helper function to read arguments of builtins which are interfaces - for the middle-end nodes like COMPLEX_EXPR, VEC_SHUFFLE_EXPR and + for the middle-end nodes like COMPLEX_EXPR, VEC_PERM_EXPR and others. The name of the builtin is passed using BNAME parameter. Function returns true if there were no errors while parsing and stores the arguments in CEXPR_LIST. */ @@ -6534,13 +6534,13 @@ c_parser_postfix_expression (c_parser *parser) if (VEC_length (c_expr_t, cexpr_list) == 2) expr.value = - c_build_vec_shuffle_expr + c_build_vec_perm_expr (loc, VEC_index (c_expr_t, cexpr_list, 0)->value, NULL_TREE, VEC_index (c_expr_t, cexpr_list, 1)->value); else if (VEC_length (c_expr_t, cexpr_list) == 3) expr.value = - c_build_vec_shuffle_expr + c_build_vec_perm_expr (loc, VEC_index (c_expr_t, cexpr_list, 0)->value, VEC_index (c_expr_t, cexpr_list, 1)->value, VEC_index (c_expr_t, cexpr_list, 2)->value); diff --git a/gcc/c-tree.h b/gcc/c-tree.h index 0e465257c78..b3e756cc076 100644 --- a/gcc/c-tree.h +++ b/gcc/c-tree.h @@ -595,7 +595,7 @@ extern tree c_begin_omp_task (void); extern tree c_finish_omp_task (location_t, tree, tree); extern tree c_finish_omp_clauses (tree); extern tree c_build_va_arg (location_t, tree, tree); -extern tree c_build_vec_shuffle_expr (location_t, tree, tree, tree); +extern tree c_build_vec_perm_expr (location_t, tree, tree, tree); /* Set to 0 at beginning of a function definition, set to 1 if a return statement that specifies a return value is seen. */ diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index e7528a715ba..6dc021080ec 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -2846,7 +2846,7 @@ build_function_call_vec (location_t loc, tree function, VEC(tree,gc) *params, return require_complete_type (result); } -/* Build a VEC_SHUFFLE_EXPR if V0, V1 and MASK are not error_mark_nodes +/* Build a VEC_PERM_EXPR if V0, V1 and MASK are not error_mark_nodes and have vector types, V0 has the same type as V1, and the number of elements of V0, V1, MASK is the same. @@ -2857,9 +2857,9 @@ build_function_call_vec (location_t loc, tree function, VEC(tree,gc) *params, an implementation accident and this semantics is not guaranteed to the user. */ tree -c_build_vec_shuffle_expr (location_t loc, tree v0, tree v1, tree mask) +c_build_vec_perm_expr (location_t loc, tree v0, tree v1, tree mask) { - tree vec_shuffle; + tree ret; bool wrap = true; bool maybe_const = false; bool two_arguments = false; @@ -2915,7 +2915,7 @@ c_build_vec_shuffle_expr (location_t loc, tree v0, tree v1, tree mask) return error_mark_node; } - /* Avoid C_MAYBE_CONST_EXPRs inside VEC_SHUFFLE_EXPR. */ + /* Avoid C_MAYBE_CONST_EXPRs inside VEC_PERM_EXPR. */ v0 = c_fully_fold (v0, false, &maybe_const); wrap &= maybe_const; @@ -2930,12 +2930,12 @@ c_build_vec_shuffle_expr (location_t loc, tree v0, tree v1, tree mask) mask = c_fully_fold (mask, false, &maybe_const); wrap &= maybe_const; - vec_shuffle = build3 (VEC_SHUFFLE_EXPR, TREE_TYPE (v0), v0, v1, mask); + ret = build3 (VEC_PERM_EXPR, TREE_TYPE (v0), v0, v1, mask); if (!wrap) - vec_shuffle = c_wrap_maybe_const (vec_shuffle, true); + ret = c_wrap_maybe_const (ret, true); - return vec_shuffle; + return ret; } /* Convert the argument expressions in the vector VALUES diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index 1495633840b..4089b40dc41 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -1858,7 +1858,8 @@ expand_call_stmt (gimple stmt) CALL_EXPR_RETURN_SLOT_OPT (exp) = gimple_call_return_slot_opt_p (stmt); if (decl && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL - && DECL_FUNCTION_CODE (decl) == BUILT_IN_ALLOCA) + && (DECL_FUNCTION_CODE (decl) == BUILT_IN_ALLOCA + || DECL_FUNCTION_CODE (decl) == BUILT_IN_ALLOCA_WITH_ALIGN)) CALL_ALLOCA_FOR_VAR_P (exp) = gimple_call_alloca_for_var_p (stmt); else CALL_FROM_THUNK_P (exp) = gimple_call_from_thunk_p (stmt); diff --git a/gcc/combine-stack-adj.c b/gcc/combine-stack-adj.c index bca078442f7..3cffd662f92 100644 --- a/gcc/combine-stack-adj.c +++ b/gcc/combine-stack-adj.c @@ -296,10 +296,11 @@ record_stack_refs (rtx *xp, void *data) return 0; } -/* If INSN has a REG_ARGS_SIZE note, move it to LAST. */ +/* If INSN has a REG_ARGS_SIZE note, move it to LAST. + AFTER is true iff LAST follows INSN in the instruction stream. */ static void -maybe_move_args_size_note (rtx last, rtx insn) +maybe_move_args_size_note (rtx last, rtx insn, bool after) { rtx note, last_note; @@ -309,7 +310,12 @@ maybe_move_args_size_note (rtx last, rtx insn) last_note = find_reg_note (last, REG_ARGS_SIZE, NULL_RTX); if (last_note) - XEXP (last_note, 0) = XEXP (note, 0); + { + /* The ARGS_SIZE notes are *not* cumulative. They represent an + absolute value, and the "most recent" note wins. */ + if (!after) + XEXP (last_note, 0) = XEXP (note, 0); + } else add_reg_note (last, REG_ARGS_SIZE, XEXP (note, 0)); } @@ -385,7 +391,7 @@ combine_stack_adjustments_for_block (basic_block bb) last_sp_adjust + this_adjust, this_adjust)) { - maybe_move_args_size_note (last_sp_set, insn); + maybe_move_args_size_note (last_sp_set, insn, false); /* It worked! */ delete_insn (insn); @@ -403,6 +409,8 @@ combine_stack_adjustments_for_block (basic_block bb) last_sp_adjust + this_adjust, -last_sp_adjust)) { + maybe_move_args_size_note (insn, last_sp_set, true); + /* It worked! */ delete_insn (last_sp_set); last_sp_set = insn; diff --git a/gcc/config.gcc b/gcc/config.gcc index 8b380ac16e4..8099ed790b3 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -3302,7 +3302,7 @@ case "${target}" in | k8 | k8-sse3 | athlon64 | athlon64-sse3 | opteron \ | opteron-sse3 | athlon-fx | bdver2 | bdver1 | btver1 \ | amdfam10 | barcelona | nocona | core2 | corei7 \ - | corei7-avx | atom) + | corei7-avx | core-avx-i | core-avx2 | atom) # OK ;; *) diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 51614396da4..2feac6f45e1 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -6550,9 +6550,26 @@ arm_legitimize_reload_address (rtx *p, int opnum, int type, int ind_levels ATTRIBUTE_UNUSED) { + /* We must recognize output that we have already generated ourselves. */ + if (GET_CODE (*p) == PLUS + && GET_CODE (XEXP (*p, 0)) == PLUS + && GET_CODE (XEXP (XEXP (*p, 0), 0)) == REG + && GET_CODE (XEXP (XEXP (*p, 0), 1)) == CONST_INT + && GET_CODE (XEXP (*p, 1)) == CONST_INT) + { + push_reload (XEXP (*p, 0), NULL_RTX, &XEXP (*p, 0), NULL, + MODE_BASE_REG_CLASS (mode), GET_MODE (*p), + VOIDmode, 0, 0, opnum, (enum reload_type) type); + return true; + } + if (GET_CODE (*p) == PLUS && GET_CODE (XEXP (*p, 0)) == REG && ARM_REGNO_OK_FOR_BASE_P (REGNO (XEXP (*p, 0))) + /* If the base register is equivalent to a constant, let the generic + code handle it. Otherwise we will run into problems if a future + reload pass decides to rematerialize the constant. */ + && !reg_equiv_constant (ORIGINAL_REGNO (XEXP (*p, 0))) && GET_CODE (XEXP (*p, 1)) == CONST_INT) { HOST_WIDE_INT val = INTVAL (XEXP (*p, 1)); diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index baa7eb41b4e..a78ba88f8ce 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -1213,27 +1213,24 @@ ; ??? Check Thumb-2 split length (define_insn_and_split "*arm_subsi3_insn" - [(set (match_operand:SI 0 "s_register_operand" "=r,r,rk,r,r") - (minus:SI (match_operand:SI 1 "reg_or_int_operand" "rI,r,k,?n,r") - (match_operand:SI 2 "reg_or_int_operand" "r,rI,r, r,?n")))] + [(set (match_operand:SI 0 "s_register_operand" "=r,r,rk,r") + (minus:SI (match_operand:SI 1 "reg_or_int_operand" "rI,r,k,?n") + (match_operand:SI 2 "reg_or_int_operand" "r,rI,r, r")))] "TARGET_32BIT" "@ rsb%?\\t%0, %2, %1 sub%?\\t%0, %1, %2 sub%?\\t%0, %1, %2 - # #" - "&& ((GET_CODE (operands[1]) == CONST_INT - && !const_ok_for_arm (INTVAL (operands[1]))) - || (GET_CODE (operands[2]) == CONST_INT - && !const_ok_for_arm (INTVAL (operands[2]))))" + "&& (GET_CODE (operands[1]) == CONST_INT + && !const_ok_for_arm (INTVAL (operands[1])))" [(clobber (const_int 0))] " arm_split_constant (MINUS, SImode, curr_insn, INTVAL (operands[1]), operands[0], operands[2], 0); DONE; " - [(set_attr "length" "4,4,4,16,16") + [(set_attr "length" "4,4,4,16") (set_attr "predicable" "yes")] ) diff --git a/gcc/config/arm/predicates.md b/gcc/config/arm/predicates.md index 27ba6033f78..2c1a138b0df 100644 --- a/gcc/config/arm/predicates.md +++ b/gcc/config/arm/predicates.md @@ -129,11 +129,12 @@ (ior (match_operand 0 "arm_rhs_operand") (match_operand 0 "memory_operand"))) +;; This doesn't have to do much because the constant is already checked +;; in the shift_operator predicate. (define_predicate "shift_amount_operand" (ior (and (match_test "TARGET_ARM") (match_operand 0 "s_register_operand")) - (and (match_code "const_int") - (match_test "((unsigned HOST_WIDE_INT) INTVAL (op)) < 32")))) + (match_operand 0 "const_int_operand"))) (define_predicate "arm_add_operand" (ior (match_operand 0 "arm_rhs_operand") @@ -219,13 +220,20 @@ (match_test "mode == GET_MODE (op)"))) ;; True for shift operators. +;; Notes: +;; * mult is only permitted with a constant shift amount +;; * patterns that permit register shift amounts only in ARM mode use +;; shift_amount_operand, patterns that always allow registers do not, +;; so we don't have to worry about that sort of thing here. (define_special_predicate "shift_operator" (and (ior (ior (and (match_code "mult") (match_test "power_of_two_operand (XEXP (op, 1), mode)")) (and (match_code "rotate") (match_test "GET_CODE (XEXP (op, 1)) == CONST_INT && ((unsigned HOST_WIDE_INT) INTVAL (XEXP (op, 1))) < 32"))) - (match_code "ashift,ashiftrt,lshiftrt,rotatert")) + (and (match_code "ashift,ashiftrt,lshiftrt,rotatert") + (match_test "GET_CODE (XEXP (op, 1)) != CONST_INT + || ((unsigned HOST_WIDE_INT) INTVAL (XEXP (op, 1))) < 32"))) (match_test "mode == GET_MODE (op)"))) ;; True for shift operators which can be used with saturation instructions. diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h index 0bbfa9b735a..eea038e3ab4 100644 --- a/gcc/config/i386/i386-protos.h +++ b/gcc/config/i386/i386-protos.h @@ -123,7 +123,7 @@ extern bool ix86_expand_int_movcc (rtx[]); extern bool ix86_expand_fp_movcc (rtx[]); extern bool ix86_expand_fp_vcond (rtx[]); extern bool ix86_expand_int_vcond (rtx[]); -extern void ix86_expand_vshuffle (rtx[]); +extern void ix86_expand_vec_perm (rtx[]); extern void ix86_expand_sse_unpack (rtx[], bool, bool); extern bool ix86_expand_int_addcc (rtx[]); extern rtx ix86_expand_call (rtx, rtx, rtx, rtx, rtx, bool); diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index faad3a53b88..21ce9b26ce9 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -3057,6 +3057,22 @@ ix86_option_override_internal (bool main_args_p) PTA_64BIT /* flags are only used for -march switch. */ }, }; + /* -mrecip options. */ + static struct + { + const char *string; /* option name */ + unsigned int mask; /* mask bits to set */ + } + const recip_options[] = + { + { "all", RECIP_MASK_ALL }, + { "none", RECIP_MASK_NONE }, + { "div", RECIP_MASK_DIV }, + { "sqrt", RECIP_MASK_SQRT }, + { "vec-div", RECIP_MASK_VEC_DIV }, + { "vec-sqrt", RECIP_MASK_VEC_SQRT }, + }; + int const pta_size = ARRAY_SIZE (processor_alias_table); /* Set up prefix/suffix so the error messages refer to either the command @@ -3814,6 +3830,56 @@ ix86_option_override_internal (bool main_args_p) target_flags &= ~MASK_VZEROUPPER; } + if (ix86_recip_name) + { + char *p = ASTRDUP (ix86_recip_name); + char *q; + unsigned int mask, i; + bool invert; + + while ((q = strtok (p, ",")) != NULL) + { + p = NULL; + if (*q == '!') + { + invert = true; + q++; + } + else + invert = false; + + if (!strcmp (q, "default")) + mask = RECIP_MASK_ALL; + else + { + for (i = 0; i < ARRAY_SIZE (recip_options); i++) + if (!strcmp (q, recip_options[i].string)) + { + mask = recip_options[i].mask; + break; + } + + if (i == ARRAY_SIZE (recip_options)) + { + error ("unknown option for -mrecip=%s", q); + invert = false; + mask = RECIP_MASK_NONE; + } + } + + recip_mask_explicit |= mask; + if (invert) + recip_mask &= ~mask; + else + recip_mask |= mask; + } + } + + if (TARGET_RECIP) + recip_mask |= RECIP_MASK_ALL & ~recip_mask_explicit; + else if (target_flags_explicit & MASK_RECIP) + recip_mask &= ~(RECIP_MASK_ALL & ~recip_mask_explicit); + /* Save the initial options in case the user does function specific options. */ if (main_args_p) @@ -3946,6 +4012,7 @@ ix86_function_specific_save (struct cl_target_option *ptr) ptr->arch_specified = ix86_arch_specified; ptr->x_ix86_isa_flags_explicit = ix86_isa_flags_explicit; ptr->ix86_target_flags_explicit = target_flags_explicit; + ptr->x_recip_mask_explicit = recip_mask_explicit; /* The fields are char but the variables are not; make sure the values fit in the fields. */ @@ -3973,6 +4040,7 @@ ix86_function_specific_restore (struct cl_target_option *ptr) ix86_arch_specified = ptr->arch_specified; ix86_isa_flags_explicit = ptr->x_ix86_isa_flags_explicit; target_flags_explicit = ptr->ix86_target_flags_explicit; + recip_mask_explicit = ptr->x_recip_mask_explicit; /* Recreate the arch feature tests if the arch changed */ if (old_arch != ix86_arch) @@ -15730,6 +15798,12 @@ ix86_fixup_binary_operands (enum rtx_code code, enum machine_mode mode, if (MEM_P (src1) && !rtx_equal_p (dst, src1)) src1 = force_reg (mode, src1); + /* Improve address combine. */ + if (code == PLUS + && GET_MODE_CLASS (mode) == MODE_INT + && MEM_P (src2)) + src2 = force_reg (mode, src2); + operands[1] = src1; operands[2] = src2; return dst; @@ -18873,7 +18947,7 @@ ix86_expand_sse_movcc (rtx dest, rtx cmp, rtx op_true, rtx op_false) enum machine_mode mode = GET_MODE (dest); rtx t2, t3, x; - if (vector_all_ones_operand (op_true, GET_MODE (op_true)) + if (vector_all_ones_operand (op_true, mode) && rtx_equal_p (op_false, CONST0_RTX (mode))) { emit_insn (gen_rtx_SET (VOIDmode, dest, cmp)); @@ -19102,7 +19176,8 @@ ix86_expand_fp_vcond (rtx operands[]) bool ix86_expand_int_vcond (rtx operands[]) { - enum machine_mode mode = GET_MODE (operands[0]); + enum machine_mode data_mode = GET_MODE (operands[0]); + enum machine_mode mode = GET_MODE (operands[4]); enum rtx_code code = GET_CODE (operands[3]); bool negate = false; rtx x, cop0, cop1; @@ -19229,32 +19304,150 @@ ix86_expand_int_vcond (rtx operands[]) } } - x = ix86_expand_sse_cmp (operands[0], code, cop0, cop1, - operands[1+negate], operands[2-negate]); + /* Allow the comparison to be done in one mode, but the movcc to + happen in another mode. */ + if (data_mode == mode) + { + x = ix86_expand_sse_cmp (operands[0], code, cop0, cop1, + operands[1+negate], operands[2-negate]); + } + else + { + gcc_assert (GET_MODE_SIZE (data_mode) == GET_MODE_SIZE (mode)); + x = ix86_expand_sse_cmp (gen_lowpart (mode, operands[0]), + code, cop0, cop1, + operands[1+negate], operands[2-negate]); + x = gen_lowpart (data_mode, x); + } ix86_expand_sse_movcc (operands[0], x, operands[1+negate], operands[2-negate]); return true; } +/* Expand a variable vector permutation. */ + void -ix86_expand_vshuffle (rtx operands[]) +ix86_expand_vec_perm (rtx operands[]) { rtx target = operands[0]; rtx op0 = operands[1]; rtx op1 = operands[2]; rtx mask = operands[3]; - rtx vt, vec[16]; + rtx t1, t2, vt, vec[16]; enum machine_mode mode = GET_MODE (op0); enum machine_mode maskmode = GET_MODE (mask); int w, e, i; bool one_operand_shuffle = rtx_equal_p (op0, op1); - gcc_checking_assert (GET_MODE_BITSIZE (mode) == 128); - /* Number of elements in the vector. */ w = GET_MODE_NUNITS (mode); e = GET_MODE_UNIT_SIZE (mode); + gcc_assert (w <= 16); + + if (TARGET_AVX2) + { + if (mode == V4DImode || mode == V4DFmode) + { + /* Unfortunately, the VPERMQ and VPERMPD instructions only support + an constant shuffle operand. With a tiny bit of effort we can + use VPERMD instead. A re-interpretation stall for V4DFmode is + unfortunate but there's no avoiding it. */ + t1 = gen_reg_rtx (V8SImode); + + /* Replicate the low bits of the V4DImode mask into V8SImode: + mask = { A B C D } + t1 = { A A B B C C D D }. */ + for (i = 0; i < 4; ++i) + vec[i*2 + 1] = vec[i*2] = GEN_INT (i * 2); + vt = gen_rtx_CONST_VECTOR (V8SImode, gen_rtvec_v (8, vec)); + vt = force_reg (V8SImode, vt); + mask = gen_lowpart (V8SImode, mask); + emit_insn (gen_avx2_permvarv8si (t1, vt, mask)); + + /* Multiply the shuffle indicies by two. */ + emit_insn (gen_avx2_lshlv8si3 (t1, t1, const1_rtx)); + + /* Add one to the odd shuffle indicies: + t1 = { A*2, A*2+1, B*2, B*2+1, ... }. */ + for (i = 0; i < 4; ++i) + { + vec[i * 2] = const0_rtx; + vec[i * 2 + 1] = const1_rtx; + } + vt = gen_rtx_CONST_VECTOR (V8SImode, gen_rtvec_v (8, vec)); + vt = force_const_mem (V8SImode, vt); + emit_insn (gen_addv8si3 (t1, t1, vt)); + + /* Continue as if V8SImode was used initially. */ + operands[3] = mask = t1; + target = gen_lowpart (V8SImode, target); + op0 = gen_lowpart (V8SImode, op0); + op1 = gen_lowpart (V8SImode, op1); + maskmode = mode = V8SImode; + w = 8; + e = 4; + } + + switch (mode) + { + case V8SImode: + /* The VPERMD and VPERMPS instructions already properly ignore + the high bits of the shuffle elements. No need for us to + perform an AND ourselves. */ + if (one_operand_shuffle) + emit_insn (gen_avx2_permvarv8si (target, mask, op0)); + else + { + t1 = gen_reg_rtx (V8SImode); + t2 = gen_reg_rtx (V8SImode); + emit_insn (gen_avx2_permvarv8si (t1, mask, op0)); + emit_insn (gen_avx2_permvarv8si (t2, mask, op1)); + goto merge_two; + } + return; + + case V8SFmode: + mask = gen_lowpart (V8SFmode, mask); + if (one_operand_shuffle) + emit_insn (gen_avx2_permvarv8sf (target, mask, op0)); + else + { + t1 = gen_reg_rtx (V8SFmode); + t2 = gen_reg_rtx (V8SFmode); + emit_insn (gen_avx2_permvarv8sf (t1, mask, op0)); + emit_insn (gen_avx2_permvarv8sf (t2, mask, op1)); + goto merge_two; + } + return; + + case V4SImode: + /* By combining the two 128-bit input vectors into one 256-bit + input vector, we can use VPERMD and VPERMPS for the full + two-operand shuffle. */ + t1 = gen_reg_rtx (V8SImode); + t2 = gen_reg_rtx (V8SImode); + emit_insn (gen_avx_vec_concatv8si (t1, op0, op1)); + emit_insn (gen_avx_vec_concatv8si (t2, mask, mask)); + emit_insn (gen_avx2_permvarv8si (t1, t2, t1)); + emit_insn (gen_avx_vextractf128v8si (target, t1, const0_rtx)); + return; + + case V4SFmode: + t1 = gen_reg_rtx (V8SFmode); + t2 = gen_reg_rtx (V8SFmode); + mask = gen_lowpart (V4SFmode, mask); + emit_insn (gen_avx_vec_concatv8sf (t1, op0, op1)); + emit_insn (gen_avx_vec_concatv8sf (t2, mask, mask)); + emit_insn (gen_avx2_permvarv8sf (t1, t2, t1)); + emit_insn (gen_avx_vextractf128v8sf (target, t1, const0_rtx)); + return; + + default: + gcc_assert (GET_MODE_SIZE (mode) <= 16); + break; + } + } if (TARGET_XOP) { @@ -19326,7 +19519,7 @@ ix86_expand_vshuffle (rtx operands[]) } else { - rtx xops[6], t1, t2; + rtx xops[6]; bool ok; /* Shuffle the two input vectors independently. */ @@ -19335,6 +19528,7 @@ ix86_expand_vshuffle (rtx operands[]) emit_insn (gen_ssse3_pshufbv16qi3 (t1, op0, mask)); emit_insn (gen_ssse3_pshufbv16qi3 (t2, op1, mask)); + merge_two: /* Then merge them together. The key is whether any given control element contained a bit set that indicates the second word. */ mask = operands[3]; @@ -19361,9 +19555,9 @@ ix86_expand_vshuffle (rtx operands[]) mask = expand_simple_binop (maskmode, AND, mask, vt, NULL_RTX, 0, OPTAB_DIRECT); - xops[0] = gen_lowpart (maskmode, operands[0]); - xops[1] = gen_lowpart (maskmode, t2); - xops[2] = gen_lowpart (maskmode, t1); + xops[0] = operands[0]; + xops[1] = gen_lowpart (mode, t2); + xops[2] = gen_lowpart (mode, t1); xops[3] = gen_rtx_EQ (maskmode, mask, vt); xops[4] = mask; xops[5] = vt; @@ -25915,7 +26109,7 @@ static const struct builtin_description bdesc_args[] = { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_ssaddv16hi3, "__builtin_ia32_paddsw256", IX86_BUILTIN_PADDSW256, UNKNOWN, (int) V16HI_FTYPE_V16HI_V16HI }, { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_usaddv32qi3, "__builtin_ia32_paddusb256", IX86_BUILTIN_PADDUSB256, UNKNOWN, (int) V32QI_FTYPE_V32QI_V32QI }, { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_usaddv16hi3, "__builtin_ia32_paddusw256", IX86_BUILTIN_PADDUSW256, UNKNOWN, (int) V16HI_FTYPE_V16HI_V16HI }, - { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_palignrv4di, "__builtin_ia32_palignr256", IX86_BUILTIN_PALIGNR256, UNKNOWN, (int) V4DI_FTYPE_V4DI_V4DI_INT_CONVERT }, + { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_palignrv2ti, "__builtin_ia32_palignr256", IX86_BUILTIN_PALIGNR256, UNKNOWN, (int) V4DI_FTYPE_V4DI_V4DI_INT_CONVERT }, { OPTION_MASK_ISA_AVX2, CODE_FOR_andv4di3, "__builtin_ia32_andsi256", IX86_BUILTIN_AND256I, UNKNOWN, (int) V4DI_FTYPE_V4DI_V4DI }, { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_andnotv4di3, "__builtin_ia32_andnotsi256", IX86_BUILTIN_ANDNOT256I, UNKNOWN, (int) V4DI_FTYPE_V4DI_V4DI }, { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_uavgv32qi3, "__builtin_ia32_pavgb256", IX86_BUILTIN_PAVGB256, UNKNOWN, (int) V32QI_FTYPE_V32QI_V32QI }, @@ -25979,7 +26173,7 @@ static const struct builtin_description bdesc_args[] = { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_psignv32qi3, "__builtin_ia32_psignb256", IX86_BUILTIN_PSIGNB256, UNKNOWN, (int) V32QI_FTYPE_V32QI_V32QI }, { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_psignv16hi3, "__builtin_ia32_psignw256", IX86_BUILTIN_PSIGNW256, UNKNOWN, (int) V16HI_FTYPE_V16HI_V16HI }, { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_psignv8si3 , "__builtin_ia32_psignd256", IX86_BUILTIN_PSIGND256, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI }, - { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_lshlqv4di3, "__builtin_ia32_pslldqi256", IX86_BUILTIN_PSLLDQI256, UNKNOWN, (int) V4DI_FTYPE_V4DI_INT }, + { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_ashlv2ti3, "__builtin_ia32_pslldqi256", IX86_BUILTIN_PSLLDQI256, UNKNOWN, (int) V4DI_FTYPE_V4DI_INT_CONVERT }, { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_lshlv16hi3, "__builtin_ia32_psllwi256", IX86_BUILTIN_PSLLWI256 , UNKNOWN, (int) V16HI_FTYPE_V16HI_SI_COUNT }, { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_lshlv16hi3, "__builtin_ia32_psllw256", IX86_BUILTIN_PSLLW256, UNKNOWN, (int) V16HI_FTYPE_V16HI_V8HI_COUNT }, { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_lshlv8si3, "__builtin_ia32_pslldi256", IX86_BUILTIN_PSLLDI256, UNKNOWN, (int) V8SI_FTYPE_V8SI_SI_COUNT }, @@ -25990,7 +26184,7 @@ static const struct builtin_description bdesc_args[] = { OPTION_MASK_ISA_AVX2, CODE_FOR_ashrv16hi3, "__builtin_ia32_psraw256", IX86_BUILTIN_PSRAW256, UNKNOWN, (int) V16HI_FTYPE_V16HI_V8HI_COUNT }, { OPTION_MASK_ISA_AVX2, CODE_FOR_ashrv8si3, "__builtin_ia32_psradi256", IX86_BUILTIN_PSRADI256, UNKNOWN, (int) V8SI_FTYPE_V8SI_SI_COUNT }, { OPTION_MASK_ISA_AVX2, CODE_FOR_ashrv8si3, "__builtin_ia32_psrad256", IX86_BUILTIN_PSRAD256, UNKNOWN, (int) V8SI_FTYPE_V8SI_V4SI_COUNT }, - { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_lshrqv4di3, "__builtin_ia32_psrldqi256", IX86_BUILTIN_PSRLDQI256, UNKNOWN, (int) V4DI_FTYPE_V4DI_INT }, + { OPTION_MASK_ISA_AVX2, CODE_FOR_avx2_lshrv2ti3, "__builtin_ia32_psrldqi256", IX86_BUILTIN_PSRLDQI256, UNKNOWN, (int) V4DI_FTYPE_V4DI_INT_CONVERT }, { OPTION_MASK_ISA_AVX2, CODE_FOR_lshrv16hi3, "__builtin_ia32_psrlwi256", IX86_BUILTIN_PSRLWI256 , UNKNOWN, (int) V16HI_FTYPE_V16HI_SI_COUNT }, { OPTION_MASK_ISA_AVX2, CODE_FOR_lshrv16hi3, "__builtin_ia32_psrlw256", IX86_BUILTIN_PSRLW256, UNKNOWN, (int) V16HI_FTYPE_V16HI_V8HI_COUNT }, { OPTION_MASK_ISA_AVX2, CODE_FOR_lshrv8si3, "__builtin_ia32_psrldi256", IX86_BUILTIN_PSRLDI256, UNKNOWN, (int) V8SI_FTYPE_V8SI_SI_COUNT }, @@ -27620,6 +27814,11 @@ ix86_expand_args_builtin (const struct builtin_description *d, rmode = V1TImode; nargs_constant = 1; break; + case V4DI_FTYPE_V4DI_INT_CONVERT: + nargs = 2; + rmode = V2TImode; + nargs_constant = 1; + break; case V8HI_FTYPE_V8HI_INT: case V8HI_FTYPE_V8SF_INT: case V8HI_FTYPE_V4SF_INT: diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index 7d6e05827b0..bd69ec2b5e3 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -2315,6 +2315,19 @@ extern void debug_dispatch_window (int); ((FLAGS) & (IX86_CALLCVT_CDECL | IX86_CALLCVT_STDCALL \ | IX86_CALLCVT_FASTCALL | IX86_CALLCVT_THISCALL)) +#define RECIP_MASK_NONE 0x00 +#define RECIP_MASK_DIV 0x01 +#define RECIP_MASK_SQRT 0x02 +#define RECIP_MASK_VEC_DIV 0x04 +#define RECIP_MASK_VEC_SQRT 0x08 +#define RECIP_MASK_ALL (RECIP_MASK_DIV | RECIP_MASK_SQRT \ + | RECIP_MASK_VEC_DIV | RECIP_MASK_VEC_SQRT) + +#define TARGET_RECIP_DIV ((recip_mask & RECIP_MASK_DIV) != 0) +#define TARGET_RECIP_SQRT ((recip_mask & RECIP_MASK_SQRT) != 0) +#define TARGET_RECIP_VEC_DIV ((recip_mask & RECIP_MASK_VEC_DIV) != 0) +#define TARGET_RECIP_VEC_SQRT ((recip_mask & RECIP_MASK_VEC_SQRT) != 0) + /* Local variables: version-control: t diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index b8a649c2ee4..a11a71b6c2e 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -7062,7 +7062,9 @@ "(TARGET_80387 && X87_ENABLE_ARITH (SFmode)) || TARGET_SSE_MATH" { - if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p () + if (TARGET_SSE_MATH + && TARGET_RECIP_DIV + && optimize_insn_for_speed_p () && flag_finite_math_only && !flag_trapping_math && flag_unsafe_math_optimizations) { @@ -13438,7 +13440,9 @@ || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" { if (<MODE>mode == SFmode - && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun) + && TARGET_SSE_MATH + && TARGET_RECIP_SQRT + && !optimize_function_for_size_p (cfun) && flag_finite_math_only && !flag_trapping_math && flag_unsafe_math_optimizations) { diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt index 8e4d51b3f9f..43009a3c2a6 100644 --- a/gcc/config/i386/i386.opt +++ b/gcc/config/i386/i386.opt @@ -31,6 +31,15 @@ HOST_WIDE_INT ix86_isa_flags = TARGET_64BIT_DEFAULT | TARGET_SUBTARGET_ISA_DEFAU Variable HOST_WIDE_INT ix86_isa_flags_explicit +TargetVariable +int recip_mask + +Variable +int recip_mask_explicit + +TargetSave +int x_recip_mask_explicit + ;; Definitions to add to the cl_target_option structure ;; -march= processor TargetSave @@ -373,6 +382,10 @@ mrecip Target Report Mask(RECIP) Save Generate reciprocals instead of divss and sqrtss. +mrecip= +Target Report RejectNegative Joined Var(ix86_recip_name) +Control generation of reciprocal estimates. + mcld Target Report Mask(CLD) Save Generate cld instruction in the function prologue. diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md index 89cc8a75b55..349f5b0c427 100644 --- a/gcc/config/i386/predicates.md +++ b/gcc/config/i386/predicates.md @@ -1210,3 +1210,12 @@ return false; return true; }) + +;; Return true if OP is a proper third operand to vpblendw256. +(define_predicate "avx2_pblendw_operand" + (match_code "const_int") +{ + HOST_WIDE_INT val = INTVAL (op); + HOST_WIDE_INT low = val & 0xff; + return val == ((low << 8) | low); +}) diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index ee9cf0b4218..f135716c583 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -18,13 +18,13 @@ ;; along with GCC; see the file COPYING3. If not see ;; <http://www.gnu.org/licenses/>. -;; All vector modes including V1TImode, used in move patterns. +;; All vector modes including V?TImode, used in move patterns. (define_mode_iterator V16 [(V32QI "TARGET_AVX") V16QI (V16HI "TARGET_AVX") V8HI (V8SI "TARGET_AVX") V4SI (V4DI "TARGET_AVX") V2DI - V1TI + (V2TI "TARGET_AVX") V1TI (V8SF "TARGET_AVX") V4SF (V4DF "TARGET_AVX") V2DF]) @@ -99,11 +99,13 @@ (define_mode_iterator VI8_AVX2 [(V4DI "TARGET_AVX2") V2DI]) +;; ??? We should probably use TImode instead. (define_mode_iterator VIMAX_AVX2 [(V2TI "TARGET_AVX2") V1TI]) +;; ??? This should probably be dropped in favor of VIMAX_AVX2. (define_mode_iterator SSESCALARMODE - [(V4DI "TARGET_AVX2") TI]) + [(V2TI "TARGET_AVX2") TI]) (define_mode_iterator VI12_AVX2 [(V32QI "TARGET_AVX2") V16QI @@ -147,7 +149,7 @@ (V8HI "ssse3") (V16HI "avx2") (V4SI "ssse3") (V8SI "avx2") (V2DI "ssse3") (V4DI "avx2") - (TI "ssse3")]) + (TI "ssse3") (V2TI "avx2")]) (define_mode_attr sse4_1_avx2 [(V16QI "sse4_1") (V32QI "avx2") @@ -230,19 +232,16 @@ (V4SF "V4SF") (V2DF "V2DF") (TI "TI")]) -;; All 128bit vector modes -(define_mode_attr sseshuffint - [(V16QI "V16QI") (V8HI "V8HI") - (V4SI "V4SI") (V2DI "V2DI") - (V4SF "V4SI") (V2DF "V2DI")]) - ;; Mapping of vector float modes to an integer mode of the same size (define_mode_attr sseintvecmode [(V8SF "V8SI") (V4DF "V4DI") (V4SF "V4SI") (V2DF "V2DI") (V4DF "V4DI") (V8SF "V8SI") (V8SI "V8SI") (V4DI "V4DI") - (V4SI "V4SI") (V2DI "V2DI")]) + (V4SI "V4SI") (V2DI "V2DI") + (V16HI "V16HI") (V8HI "V8HI") + (V32QI "V32QI") (V16QI "V16QI") + ]) ;; Mapping of vector modes to a vector mode of double size (define_mode_attr ssedoublevecmode @@ -779,7 +778,9 @@ { ix86_fixup_binary_operands_no_copy (DIV, <MODE>mode, operands); - if (TARGET_SSE_MATH && TARGET_RECIP && !optimize_insn_for_size_p () + if (TARGET_SSE_MATH + && TARGET_RECIP_VEC_DIV + && !optimize_insn_for_size_p () && flag_finite_math_only && !flag_trapping_math && flag_unsafe_math_optimizations) { @@ -857,7 +858,9 @@ (sqrt:VF1 (match_operand:VF1 1 "nonimmediate_operand" "")))] "TARGET_SSE" { - if (TARGET_SSE_MATH && TARGET_RECIP && !optimize_insn_for_size_p () + if (TARGET_SSE_MATH + && TARGET_RECIP_VEC_SQRT + && !optimize_insn_for_size_p () && flag_finite_math_only && !flag_trapping_math && flag_unsafe_math_optimizations) { @@ -5648,21 +5651,6 @@ (set_attr "prefix" "orig,vex") (set_attr "mode" "<sseinsnmode>")]) -(define_insn "avx2_lshrqv4di3" - [(set (match_operand:V4DI 0 "register_operand" "=x") - (lshiftrt:V4DI - (match_operand:V4DI 1 "register_operand" "x") - (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))] - "TARGET_AVX2" -{ - operands[2] = GEN_INT (INTVAL (operands[2]) / 8); - return "vpsrldq\t{%2, %1, %0|%0, %1, %2}"; -} - [(set_attr "type" "sseishft") - (set_attr "prefix" "vex") - (set_attr "length_immediate" "1") - (set_attr "mode" "OI")]) - (define_insn "lshr<mode>3" [(set (match_operand:VI248_AVX2 0 "register_operand" "=x,x") (lshiftrt:VI248_AVX2 @@ -5682,20 +5670,6 @@ (set_attr "prefix" "orig,vex") (set_attr "mode" "<sseinsnmode>")]) -(define_insn "avx2_lshlqv4di3" - [(set (match_operand:V4DI 0 "register_operand" "=x") - (ashift:V4DI (match_operand:V4DI 1 "register_operand" "x") - (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))] - "TARGET_AVX2" -{ - operands[2] = GEN_INT (INTVAL (operands[2]) / 8); - return "vpslldq\t{%2, %1, %0|%0, %1, %2}"; -} - [(set_attr "type" "sseishft") - (set_attr "prefix" "vex") - (set_attr "length_immediate" "1") - (set_attr "mode" "OI")]) - (define_insn "avx2_lshl<mode>3" [(set (match_operand:VI248_256 0 "register_operand" "=x") (ashift:VI248_256 @@ -6222,14 +6196,22 @@ DONE; }) -(define_expand "vshuffle<mode>" - [(match_operand:V_128 0 "register_operand" "") - (match_operand:V_128 1 "register_operand" "") - (match_operand:V_128 2 "register_operand" "") - (match_operand:<sseshuffint> 3 "register_operand" "")] - "TARGET_SSSE3 || TARGET_AVX" +;; ??? Irritatingly, the 256-bit VPSHUFB only shuffles within the 128-bit +;; lanes. For now, we don't try to support V32QI or V16HImode. So we +;; don't want to use VI_AVX2. +(define_mode_iterator VEC_PERM_AVX2 + [V16QI V8HI V4SI V2DI V4SF V2DF + (V8SI "TARGET_AVX2") (V4DI "TARGET_AVX2") + (V8SF "TARGET_AVX2") (V4DF "TARGET_AVX2")]) + +(define_expand "vec_perm<mode>" + [(match_operand:VEC_PERM_AVX2 0 "register_operand" "") + (match_operand:VEC_PERM_AVX2 1 "register_operand" "") + (match_operand:VEC_PERM_AVX2 2 "register_operand" "") + (match_operand:<sseintvecmode> 3 "register_operand" "")] + "TARGET_SSSE3 || TARGET_AVX || TARGET_XOP" { - ix86_expand_vshuffle (operands); + ix86_expand_vec_perm (operands); DONE; }) @@ -9435,11 +9417,11 @@ (set_attr "prefix" "orig,vex") (set_attr "mode" "<sseinsnmode>")]) -(define_insn "<sse4_1_avx2>_pblendw" - [(set (match_operand:VI2_AVX2 0 "register_operand" "=x,x") - (vec_merge:VI2_AVX2 - (match_operand:VI2_AVX2 2 "nonimmediate_operand" "xm,xm") - (match_operand:VI2_AVX2 1 "register_operand" "0,x") +(define_insn "sse4_1_pblendw" + [(set (match_operand:V8HI 0 "register_operand" "=x,x") + (vec_merge:V8HI + (match_operand:V8HI 2 "nonimmediate_operand" "xm,xm") + (match_operand:V8HI 1 "register_operand" "0,x") (match_operand:SI 3 "const_0_to_255_operand" "n,n")))] "TARGET_SSE4_1" "@ @@ -9450,7 +9432,37 @@ (set_attr "prefix_extra" "1") (set_attr "length_immediate" "1") (set_attr "prefix" "orig,vex") - (set_attr "mode" "<sseinsnmode>")]) + (set_attr "mode" "TI")]) + +;; The builtin uses an 8-bit immediate. Expand that. +(define_expand "avx2_pblendw" + [(set (match_operand:V16HI 0 "register_operand" "") + (vec_merge:V16HI + (match_operand:V16HI 2 "nonimmediate_operand" "") + (match_operand:V16HI 1 "register_operand" "") + (match_operand:SI 3 "const_0_to_255_operand" "")))] + "TARGET_AVX2" +{ + HOST_WIDE_INT val = INTVAL (operands[3]) & 0xff; + operands[3] = GEN_INT (val << 8 | val); +}) + +(define_insn "*avx2_pblendw" + [(set (match_operand:V16HI 0 "register_operand" "=x") + (vec_merge:V16HI + (match_operand:V16HI 2 "nonimmediate_operand" "xm") + (match_operand:V16HI 1 "register_operand" "x") + (match_operand:SI 3 "avx2_pblendw_operand" "n")))] + "TARGET_AVX2" +{ + operands[3] = GEN_INT (INTVAL (operands[3]) & 0xff); + return "vpblendw\t{%3, %2, %1, %0|%0, %1, %2, %3}"; +} + [(set_attr "type" "ssemov") + (set_attr "prefix_extra" "1") + (set_attr "length_immediate" "1") + (set_attr "prefix" "vex") + (set_attr "mode" "OI")]) (define_insn "avx2_pblendd<mode>" [(set (match_operand:VI4_AVX2 0 "register_operand" "=x") @@ -12393,7 +12405,7 @@ (set_attr "prefix" "vex") (set_attr "mode" "TI")]) -(define_insn "*vec_concat<mode>_avx" +(define_insn "avx_vec_concat<mode>" [(set (match_operand:V_256 0 "register_operand" "=x,x") (vec_concat:V_256 (match_operand:<ssehalfvecmode> 1 "register_operand" "x,x") diff --git a/gcc/config/rs6000/aix.h b/gcc/config/rs6000/aix.h index 2c678a3a247..29eabbb6fd8 100644 --- a/gcc/config/rs6000/aix.h +++ b/gcc/config/rs6000/aix.h @@ -97,6 +97,9 @@ { \ builtin_define ("_IBMR2"); \ builtin_define ("_POWER"); \ + builtin_define ("__powerpc__"); \ + builtin_define ("__PPC__"); \ + builtin_define ("__unix__"); \ builtin_define ("_AIX"); \ builtin_define ("_AIX32"); \ builtin_define ("_AIX41"); \ diff --git a/gcc/config/rx/rx.md b/gcc/config/rx/rx.md index 708f9444ca9..a55b62f8f57 100644 --- a/gcc/config/rx/rx.md +++ b/gcc/config/rx/rx.md @@ -1199,11 +1199,11 @@ (set_attr "timings" "11,11,11,11,11,33")] ) -(define_insn "smin<int_modes:mode>3" - [(set (match_operand:int_modes 0 "register_operand" "=r,r,r,r,r,r") - (smin:int_modes (match_operand:int_modes 1 "register_operand" "%0,0,0,0,0,0") - (match_operand:int_modes 2 "rx_source_operand" - "r,Sint08,Sint16,Sint24,i,Q")))] +(define_insn "sminsi3" + [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r") + (smin:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0") + (match_operand:SI 2 "rx_source_operand" + "r,Sint08,Sint16,Sint24,i,Q")))] "" "min\t%Q2, %0" [(set_attr "length" "3,4,5,6,7,6") diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index 22f05f9fd21..ffca91a107a 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -3604,7 +3604,8 @@ s390_emit_tls_call_insn (rtx result_reg, rtx tls_call) { rtx insn; - gcc_assert (flag_pic); + if (!flag_pic) + emit_insn (s390_load_got ()); if (!s390_tls_symbol) s390_tls_symbol = gen_rtx_SYMBOL_REF (Pmode, "__tls_get_offset"); @@ -7859,6 +7860,12 @@ s390_load_got (void) { rtx insns; + /* We cannot use pic_offset_table_rtx here since we use this + function also for non-pic if __tls_get_offset is called and in + that case PIC_OFFSET_TABLE_REGNUM as well as pic_offset_table_rtx + aren't usable. */ + rtx got_rtx = gen_rtx_REG (Pmode, 12); + if (!got_symbol) { got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_"); @@ -7869,7 +7876,7 @@ s390_load_got (void) if (TARGET_CPU_ZARCH) { - emit_move_insn (pic_offset_table_rtx, got_symbol); + emit_move_insn (got_rtx, got_symbol); } else { @@ -7880,13 +7887,13 @@ s390_load_got (void) offset = gen_rtx_CONST (Pmode, offset); offset = force_const_mem (Pmode, offset); - emit_move_insn (pic_offset_table_rtx, offset); + emit_move_insn (got_rtx, offset); offset = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, XEXP (offset, 0)), UNSPEC_LTREL_BASE); - offset = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, offset); + offset = gen_rtx_PLUS (Pmode, got_rtx, offset); - emit_move_insn (pic_offset_table_rtx, offset); + emit_move_insn (got_rtx, offset); } insns = get_insns (); @@ -9827,8 +9834,7 @@ s390_emit_call (rtx addr_location, rtx tls_call, rtx result_reg, /* s390_function_ok_for_sibcall should have denied sibcalls in this case. */ gcc_assert (retaddr_reg != NULL_RTX); - - use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx); + use_reg (&CALL_INSN_FUNCTION_USAGE (insn), gen_rtx_REG (Pmode, 12)); } return insn; } diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md index 018f6b49214..4c9a40f6e8e 100644 --- a/gcc/config/s390/s390.md +++ b/gcc/config/s390/s390.md @@ -367,6 +367,10 @@ (define_mode_iterator DW [(TI "TARGET_ZARCH") (DI "!TARGET_ZARCH")]) (define_mode_iterator W [(DI "TARGET_ZARCH") (SI "!TARGET_ZARCH")]) +;; Used by the umul pattern to express modes having half the size. +(define_mode_attr DWH [(TI "DI") (DI "SI")]) +(define_mode_attr dwh [(TI "di") (DI "si")]) + ;; This mode iterator allows the QI and HI patterns to be defined from ;; the same template. (define_mode_iterator HQI [HI QI]) @@ -5456,21 +5460,22 @@ (set_attr "cpu_facility" "*,*,z10")]) ; -; umulsidi3 instruction pattern(s). +; umul instruction pattern(s). ; -(define_insn "umulsidi3" - [(set (match_operand:DI 0 "register_operand" "=d,d") - (mult:DI (zero_extend:DI - (match_operand:SI 1 "register_operand" "%0,0")) - (zero_extend:DI - (match_operand:SI 2 "nonimmediate_operand" "d,RT"))))] - "!TARGET_ZARCH && TARGET_CPU_ZARCH" +; mlr, ml, mlgr, mlg +(define_insn "umul<dwh><mode>3" + [(set (match_operand:DW 0 "register_operand" "=d, d") + (mult:DW (zero_extend:DW + (match_operand:<DWH> 1 "register_operand" "%0, 0")) + (zero_extend:DW + (match_operand:<DWH> 2 "nonimmediate_operand" " d,RT"))))] + "TARGET_CPU_ZARCH" "@ - mlr\t%0,%2 - ml\t%0,%2" + ml<tg>r\t%0,%2 + ml<tg>\t%0,%2" [(set_attr "op_type" "RRE,RXY") - (set_attr "type" "imulsi")]) + (set_attr "type" "imul<dwh>")]) ; ; mul(tf|df|sf|td|dd)3 instruction pattern(s). diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md index 15552b2b1c9..a6eba6ca3a6 100644 --- a/gcc/config/sparc/sparc.md +++ b/gcc/config/sparc/sparc.md @@ -206,8 +206,6 @@ (define_mode_iterator V64N8 [V2SI V4HI]) -(define_mode_iterator SIDI [SI DI]) - ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding @@ -6806,36 +6804,24 @@ [(set_attr "type" "multi") (set_attr "length" "8")]) -(define_expand "popcount<mode>2" - [(set (match_operand:SIDI 0 "register_operand" "") - (popcount:SIDI (match_operand:SIDI 1 "register_operand" "")))] +(define_expand "popcountdi2" + [(set (match_operand:DI 0 "register_operand" "") + (popcount:DI (match_operand:DI 1 "register_operand" "")))] "TARGET_POPC" { if (! TARGET_ARCH64) { - emit_insn (gen_popcount<mode>_v8plus (operands[0], operands[1])); + emit_insn (gen_popcountdi_v8plus (operands[0], operands[1])); DONE; } }) -(define_insn "*popcount<mode>_sp64" - [(set (match_operand:SIDI 0 "register_operand" "=r") - (popcount:SIDI (match_operand:SIDI 1 "register_operand" "r")))] +(define_insn "*popcountdi_sp64" + [(set (match_operand:DI 0 "register_operand" "=r") + (popcount:DI (match_operand:DI 1 "register_operand" "r")))] "TARGET_POPC && TARGET_ARCH64" "popc\t%1, %0") -(define_insn "popcountsi_v8plus" - [(set (match_operand:SI 0 "register_operand" "=r") - (popcount:SI (match_operand:SI 1 "register_operand" "r")))] - "TARGET_POPC && ! TARGET_ARCH64" -{ - if (sparc_check_64 (operands[1], insn) <= 0) - output_asm_insn ("srl\t%1, 0, %1", operands); - return "popc\t%1, %0"; -} - [(set_attr "type" "multi") - (set_attr "length" "2")]) - (define_insn "popcountdi_v8plus" [(set (match_operand:DI 0 "register_operand" "=r") (popcount:DI (match_operand:DI 1 "register_operand" "r"))) @@ -6849,14 +6835,49 @@ [(set_attr "type" "multi") (set_attr "length" "5")]) -(define_expand "clz<mode>2" - [(set (match_operand:SIDI 0 "register_operand" "") - (clz:SIDI (match_operand:SIDI 1 "register_operand" "")))] +(define_expand "popcountsi2" + [(set (match_dup 2) + (zero_extend:DI (match_operand:SI 1 "register_operand" ""))) + (set (match_operand:SI 0 "register_operand" "") + (truncate:SI (popcount:DI (match_dup 2))))] + "TARGET_POPC" +{ + if (! TARGET_ARCH64) + { + emit_insn (gen_popcountsi_v8plus (operands[0], operands[1])); + DONE; + } + else + operands[2] = gen_reg_rtx (DImode); +}) + +(define_insn "*popcountsi_sp64" + [(set (match_operand:SI 0 "register_operand" "=r") + (truncate:SI + (popcount:DI (match_operand:DI 1 "register_operand" "r"))))] + "TARGET_POPC && TARGET_ARCH64" + "popc\t%1, %0") + +(define_insn "popcountsi_v8plus" + [(set (match_operand:SI 0 "register_operand" "=r") + (popcount:SI (match_operand:SI 1 "register_operand" "r")))] + "TARGET_POPC && ! TARGET_ARCH64" +{ + if (sparc_check_64 (operands[1], insn) <= 0) + output_asm_insn ("srl\t%1, 0, %1", operands); + return "popc\t%1, %0"; +} + [(set_attr "type" "multi") + (set_attr "length" "2")]) + +(define_expand "clzdi2" + [(set (match_operand:DI 0 "register_operand" "") + (clz:DI (match_operand:DI 1 "register_operand" "")))] "TARGET_VIS3" { if (! TARGET_ARCH64) { - emit_insn (gen_clz<mode>_v8plus (operands[0], operands[1])); + emit_insn (gen_clzdi_v8plus (operands[0], operands[1])); DONE; } }) @@ -6880,13 +6901,33 @@ [(set_attr "type" "multi") (set_attr "length" "5")]) +(define_expand "clzsi2" + [(set (match_dup 2) + (zero_extend:DI (match_operand:SI 1 "register_operand" ""))) + (set (match_dup 3) + (truncate:SI (clz:DI (match_dup 2)))) + (set (match_operand:SI 0 "register_operand" "") + (minus:SI (match_dup 3) (const_int 32)))] + "TARGET_VIS3" +{ + if (! TARGET_ARCH64) + { + emit_insn (gen_clzsi_v8plus (operands[0], operands[1])); + DONE; + } + else + { + operands[2] = gen_reg_rtx (DImode); + operands[3] = gen_reg_rtx (SImode); + } +}) + (define_insn "*clzsi_sp64" [(set (match_operand:SI 0 "register_operand" "=r") - (clz:SI (match_operand:SI 1 "register_operand" "r")))] + (truncate:SI + (clz:DI (match_operand:DI 1 "register_operand" "r"))))] "TARGET_VIS3 && TARGET_ARCH64" - "lzd\t%1, %0\n\tsub\t%0, 32, %0" - [(set_attr "type" "multi") - (set_attr "length" "2")]) + "lzd\t%1, %0") (define_insn "clzsi_v8plus" [(set (match_operand:SI 0 "register_operand" "=r") diff --git a/gcc/configure b/gcc/configure index ac327053bc9..cb55ddaa2a4 100755 --- a/gcc/configure +++ b/gcc/configure @@ -24060,6 +24060,8 @@ else gcc_cv_as_sparc_fmaf=no if test x$gcc_cv_as != x; then $as_echo '.text + .register %g2, #scratch + .register %g3, #scratch .align 4 fmaddd %f0, %f2, %f4, %f6 addxccc %g1, %g2, %g3 diff --git a/gcc/configure.ac b/gcc/configure.ac index ed52c918afa..a7b94e64451 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -3491,6 +3491,8 @@ foo: gcc_cv_as_sparc_fmaf,, [-xarch=v9d], [.text + .register %g2, #scratch + .register %g3, #scratch .align 4 fmaddd %f0, %f2, %f4, %f6 addxccc %g1, %g2, %g3 diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index c8ca7c5f85a..c27d8a627e8 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,35 @@ +2011-10-09 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/38980 + * init.c (constant_value_1): Add bool parameter. + (decl_constant_value_safe): Add. + (integral_constant_value): Adjust. + (decl_constant_value): Adjust. + * cp-tree.h (decl_constant_value_safe): Declare. + * typeck.c (decay_conversion): Use decl_constant_value_safe. + * call.c (convert_like_real): Likewise. + +2011-10-09 Jakub Jelinek <jakub@redhat.com> + Diego Novillo <dnovillo@google.com> + + * pt.c (reregister_specialization): Use htab_find instead of + htab_find_slot with INSERT. + (maybe_process_partial_specialization, lookup_template_class_1): Change + slot variable type to void ** to avoid aliasing problems. + (register_specialization): Likewise. Use slot != NULL instead of + more expensive !optimize_specialization_lookup_p (tmpl) test. + +2011-10-08 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/34927 + * typeck2.c (abstract_virtuals_error_sfinae): Don't produce duplicate + inform messages in case of cloned destructor. + +2011-10-06 Jason Merrill <jason@redhat.com> + + PR c++/39164 + * decl.c (grokfndecl): Diagnose redefinition of defaulted fn. + 2011-10-02 Jason Merrill <jason@redhat.com> * pt.c (tsubst_pack_expansion): Re-use ARGUMENT_PACK_SELECTs. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index a52ec29eb66..ee71d9ba6c9 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -5703,7 +5703,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, leave it as an lvalue. */ if (inner >= 0) { - expr = decl_constant_value (expr); + expr = decl_constant_value_safe (expr); if (expr == null_node && INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (totype)) /* If __null has been converted to an integer type, we do not want to warn about uses of EXPR as an integer, rather than diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 7e5aac750f3..f824f38b74a 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -5097,6 +5097,7 @@ extern tree create_temporary_var (tree); extern void initialize_vtbl_ptrs (tree); extern tree build_java_class_ref (tree); extern tree integral_constant_value (tree); +extern tree decl_constant_value_safe (tree); extern int diagnose_uninitialized_cst_or_ref_member (tree, bool, bool); /* in lex.c */ diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 30f92dae243..984d1f2f372 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -7418,6 +7418,12 @@ grokfndecl (tree ctype, error ("definition of implicitly-declared %qD", old_decl); return NULL_TREE; } + else if (DECL_DEFAULTED_FN (old_decl)) + { + error ("definition of explicitly-defaulted %q+D", decl); + error ("%q+#D explicitly defaulted here", old_decl); + return NULL_TREE; + } /* Since we've smashed OLD_DECL to its DECL_TEMPLATE_RESULT, we must do the same to DECL. */ diff --git a/gcc/cp/init.c b/gcc/cp/init.c index f246286e767..7897fffb684 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -1794,10 +1794,11 @@ build_offset_ref (tree type, tree member, bool address_p) constant initializer, return the initializer (or, its initializers, recursively); otherwise, return DECL. If INTEGRAL_P, the initializer is only returned if DECL is an integral - constant-expression. */ + constant-expression. If RETURN_AGGREGATE_CST_OK_P, it is ok to + return an aggregate constant. */ static tree -constant_value_1 (tree decl, bool integral_p) +constant_value_1 (tree decl, bool integral_p, bool return_aggregate_cst_ok_p) { while (TREE_CODE (decl) == CONST_DECL || (integral_p @@ -1834,12 +1835,13 @@ constant_value_1 (tree decl, bool integral_p) if (!init || !TREE_TYPE (init) || !TREE_CONSTANT (init) - || (!integral_p - /* Do not return an aggregate constant (of which - string literals are a special case), as we do not - want to make inadvertent copies of such entities, - and we must be sure that their addresses are the - same everywhere. */ + || (!integral_p && !return_aggregate_cst_ok_p + /* Unless RETURN_AGGREGATE_CST_OK_P is true, do not + return an aggregate constant (of which string + literals are a special case), as we do not want + to make inadvertent copies of such entities, and + we must be sure that their addresses are the + same everywhere. */ && (TREE_CODE (init) == CONSTRUCTOR || TREE_CODE (init) == STRING_CST))) break; @@ -1856,18 +1858,28 @@ constant_value_1 (tree decl, bool integral_p) tree integral_constant_value (tree decl) { - return constant_value_1 (decl, /*integral_p=*/true); + return constant_value_1 (decl, /*integral_p=*/true, + /*return_aggregate_cst_ok_p=*/false); } /* A more relaxed version of integral_constant_value, used by the - common C/C++ code and by the C++ front end for optimization - purposes. */ + common C/C++ code. */ tree decl_constant_value (tree decl) { - return constant_value_1 (decl, - /*integral_p=*/processing_template_decl); + return constant_value_1 (decl, /*integral_p=*/processing_template_decl, + /*return_aggregate_cst_ok_p=*/true); +} + +/* A version of integral_constant_value used by the C++ front end for + optimization purposes. */ + +tree +decl_constant_value_safe (tree decl) +{ + return constant_value_1 (decl, /*integral_p=*/processing_template_decl, + /*return_aggregate_cst_ok_p=*/false); } /* Common subroutines of build_new and build_vec_delete. */ diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 051c89a7eff..c95f1cb6436 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -892,7 +892,8 @@ maybe_process_partial_specialization (tree type) instantiation. Reassign it to the new member specialization template. */ spec_entry elt; - spec_entry **slot; + spec_entry *entry; + void **slot; elt.tmpl = most_general_template (tmpl); elt.args = CLASSTYPE_TI_ARGS (inst); @@ -903,10 +904,10 @@ maybe_process_partial_specialization (tree type) elt.tmpl = tmpl; elt.args = INNERMOST_TEMPLATE_ARGS (elt.args); - slot = (spec_entry **) - htab_find_slot (type_specializations, &elt, INSERT); - *slot = ggc_alloc_spec_entry (); - **slot = elt; + slot = htab_find_slot (type_specializations, &elt, INSERT); + entry = ggc_alloc_spec_entry (); + *entry = elt; + *slot = entry; } else if (COMPLETE_OR_OPEN_TYPE_P (inst)) /* But if we've had an implicit instantiation, that's a @@ -1294,7 +1295,7 @@ register_specialization (tree spec, tree tmpl, tree args, bool is_friend, hashval_t hash) { tree fn; - spec_entry **slot = NULL; + void **slot = NULL; spec_entry elt; gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL && DECL_P (spec)); @@ -1327,10 +1328,10 @@ register_specialization (tree spec, tree tmpl, tree args, bool is_friend, if (hash == 0) hash = hash_specialization (&elt); - slot = (spec_entry **) + slot = htab_find_slot_with_hash (decl_specializations, &elt, hash, INSERT); if (*slot) - fn = (*slot)->spec; + fn = ((spec_entry *) *slot)->spec; else fn = NULL_TREE; } @@ -1423,11 +1424,12 @@ register_specialization (tree spec, tree tmpl, tree args, bool is_friend, && !check_specialization_namespace (tmpl)) DECL_CONTEXT (spec) = DECL_CONTEXT (tmpl); - if (!optimize_specialization_lookup_p (tmpl)) + if (slot != NULL /* !optimize_specialization_lookup_p (tmpl) */) { + spec_entry *entry = ggc_alloc_spec_entry (); gcc_assert (tmpl && args && spec); - *slot = ggc_alloc_spec_entry (); - **slot = elt; + *entry = elt; + *slot = entry; if (TREE_CODE (spec) == FUNCTION_DECL && DECL_NAMESPACE_SCOPE_P (spec) && PRIMARY_TEMPLATE_P (tmpl) && DECL_SAVED_TREE (DECL_TEMPLATE_RESULT (tmpl)) == NULL_TREE) @@ -1639,19 +1641,19 @@ iterative_hash_template_arg (tree arg, hashval_t val) bool reregister_specialization (tree spec, tree tinfo, tree new_spec) { - spec_entry **slot; + spec_entry *entry; spec_entry elt; elt.tmpl = most_general_template (TI_TEMPLATE (tinfo)); elt.args = TI_ARGS (tinfo); elt.spec = NULL_TREE; - slot = (spec_entry **) htab_find_slot (decl_specializations, &elt, INSERT); - if (*slot) + entry = (spec_entry *) htab_find (decl_specializations, &elt); + if (entry != NULL) { - gcc_assert ((*slot)->spec == spec || (*slot)->spec == new_spec); + gcc_assert (entry->spec == spec || entry->spec == new_spec); gcc_assert (new_spec != NULL_TREE); - (*slot)->spec = new_spec; + entry->spec = new_spec; return 1; } @@ -7042,7 +7044,7 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context, { tree templ = NULL_TREE, parmlist; tree t; - spec_entry **slot; + void **slot; spec_entry *entry; spec_entry elt; hashval_t hash; @@ -7480,10 +7482,11 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context, SET_TYPE_TEMPLATE_INFO (t, build_template_info (found, arglist)); elt.spec = t; - slot = (spec_entry **) htab_find_slot_with_hash (type_specializations, - &elt, hash, INSERT); - *slot = ggc_alloc_spec_entry (); - **slot = elt; + slot = htab_find_slot_with_hash (type_specializations, + &elt, hash, INSERT); + entry = ggc_alloc_spec_entry (); + *entry = elt; + *slot = entry; /* Note this use of the partial instantiation so we can check it later in maybe_process_partial_specialization. */ diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index d416b42db3b..305f8f5b937 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -1827,7 +1827,7 @@ decay_conversion (tree exp) /* FIXME remove? at least need to remember that this isn't really a constant expression if EXP isn't decl_constant_var_p, like with C_MAYBE_CONST_EXPR. */ - exp = decl_constant_value (exp); + exp = decl_constant_value_safe (exp); if (error_operand_p (exp)) return error_mark_node; diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index 96b95c2b5ce..3accab62133 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -340,7 +340,10 @@ abstract_virtuals_error_sfinae (tree decl, tree type, tsubst_flags_t complain) type); FOR_EACH_VEC_ELT (tree, pure, ix, fn) - inform (input_location, "\t%+#D", fn); + if (! DECL_CLONED_FUNCTION_P (fn) + || DECL_COMPLETE_DESTRUCTOR_P (fn)) + inform (input_location, "\t%+#D", fn); + /* Now truncate the vector. This leaves it non-null, so we know there are pure virtuals, but empty so we don't list them out again. */ diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index c3ebf095fd0..11118edc1d6 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -6586,16 +6586,18 @@ c = a == b; /* The result would be @{0,-1, 0,-1@} */ Vector shuffling is available using functions @code{__builtin_shuffle (vec, mask)} and -@code{__builtin_shuffle (vec0, vec1, mask)}. Both functions construct -a permutation of elements from one or two vectors and return a vector -of the same type as input vector(s). The mask is a vector of -integer-typed elements. The size of each element of the mask must be -the same as the size of each input vector element. The number of -elements in input vector(s) and mask must be the same. +@code{__builtin_shuffle (vec0, vec1, mask)}. +Both functions construct a permutation of elements from one or two +vectors and return a vector of the same type as the input vector(s). +The @var{mask} is an integral vector with the same width (@var{W}) +and element count (@var{N}) as the output vector. -The elements of the input vectors are numbered from left to right across -one or both of the vectors. Each element in the mask specifies a number -of element from the input vector(s). Consider the following example. +The elements of the input vectors are numbered in memory ordering of +@var{vec0} beginning at 0 and @var{vec1} beginning at @var{N}. The +elements of @var{mask} are considered modulo @var{N} in the single-operand +case and modulo @math{2*@var{N}} in the two-operand case. + +Consider the following example, @smallexample typedef int v4si __attribute__ ((vector_size (16))); @@ -6610,6 +6612,9 @@ res = __builtin_shuffle (a, mask1); /* res is @{1,2,2,4@} */ res = __builtin_shuffle (a, b, mask2); /* res is @{1,5,3,6@} */ @end smallexample +Note that @code{__builtin_shuffle} is intentionally semantically +compatible with the OpenCL @code{shuffle} and @code{shuffle2} functions. + You can declare variables and use them in function calls and returns, as well as in assignments and some casts. You can specify a vector type as a return type for a function. Vector types can also be used as function @@ -6620,20 +6625,6 @@ to and from other datatypes of the same size). You cannot operate between vectors of different lengths or different signedness without a cast. -A port that supports hardware vector operations, usually provides a set -of built-in functions that can be used to operate on vectors. For -example, a function to add two vectors and multiply the result by a -third could look like this: - -@smallexample -v4si f (v4si a, v4si b, v4si c) -@{ - v4si tmp = __builtin_addv4si (a, b); - return __builtin_mulv4si (tmp, c); -@} - -@end smallexample - @node Offsetof @section Offsetof @findex __builtin_offsetof diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index c3095000fbf..634dd53a5f4 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -606,7 +606,9 @@ Objective-C and Objective-C++ Dialects}. -mno-wide-multiply -mrtd -malign-double @gol -mpreferred-stack-boundary=@var{num} @gol -mincoming-stack-boundary=@var{num} @gol --mcld -mcx16 -msahf -mmovbe -mcrc32 -mrecip -mvzeroupper @gol +-mcld -mcx16 -msahf -mmovbe -mcrc32 @gol +-mrecip -mrecip=@var{opt} @gol +-mvzeroupper @gol -mmmx -msse -msse2 -msse3 -mssse3 -msse4.1 -msse4.2 -msse4 -mavx @gol -mavx2 -maes -mpclmul -mfsgsbase -mrdrnd -mf16c -mfma @gol -msse4a -m3dnow -mpopcnt -mabm -mbmi -mtbm -mfma4 -mxop -mlzcnt @gol @@ -12877,6 +12879,22 @@ Note that GCC implements 1.0f/sqrtf(x) in terms of RSQRTSS (or RSQRTPS) already with @option{-ffast-math} (or the above option combination), and doesn't need @option{-mrecip}. +@item -mrecip=@var{opt} +@opindex mrecip=opt +This option allows to control which reciprocal estimate instructions +may be used. @var{opt} is a comma separated list of options, that may +be preceded by a @code{!} to invert the option: +@code{all}: enable all estimate instructions, +@code{default}: enable the default instructions, equivalent to @option{-mrecip}, +@code{none}: disable all estimate instructions, equivalent to @option{-mno-recip}, +@code{div}: enable the approximation for scalar division, +@code{vec-div}: enable the approximation for vectorized division, +@code{sqrt}: enable the approximation for scalar square root, +@code{vec-sqrt}: enable the approximation for vectorized square root. + +So for example, @option{-mrecip=all,!sqrt} would enable +all of the reciprocal approximations, except for square root. + @item -mveclibabi=@var{type} @opindex mveclibabi Specifies the ABI type to use for vectorizing intrinsics using an diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi index 1aa8552c5d4..b61a99b3df7 100644 --- a/gcc/doc/md.texi +++ b/gcc/doc/md.texi @@ -4028,6 +4028,34 @@ will be set to the value @var{op1} & @var{msk} | @var{op2} & ~@var{msk} where @var{msk} is computed by element-wise evaluation of the vector comparison with a truth value of all-ones and a false value of all-zeros. +@cindex @code{vec_perm@var{m}} instruction pattern +@item @samp{vec_perm@var{m}} +Output a (variable) vector permutation. Operand 0 is the destination +to receive elements from operand 1 and operand 2, which are of mode +@var{m}. Operand 3 is the @dfn{selector}. It is an integral mode +vector of the same width and number of elements as mode @var{m}. + +The input elements are numbered from 0 in operand 1 through +@math{2*@var{N}-1} in operand 2. The elements of the selector must +be computed modulo @math{2*@var{N}}. Note that if +@code{rtx_equal_p(operand1, operand2)}, this can be implemented +with just operand 1 and selector elements modulo @var{N}. + +@cindex @code{vec_perm_const@var{m}) instruction pattern +@item @samp{vec_perm_const@var{m}} +Like @samp{vec_perm} except that the permutation is a compile-time +constant. That is, operand 3, the @dfn{selector}, is a @code{CONST_VECTOR}. + +Some targets cannot perform a permutation with a variable selector, +but can efficiently perform a constant permutation. Further, the +target hook @code{vec_perm_ok} is queried to determine if the +specific constant permutation is available efficiently; the named +pattern is never expanded without @code{vec_perm_ok} returning true. + +There is no need for a target to supply both @samp{vec_perm@var{m}} +and @samp{vec_perm_const@var{m}} if the former can trivially implement +the operation with, say, the vector constant loaded into a register. + @cindex @code{push@var{m}1} instruction pattern @item @samp{push@var{m}1} Output a push instruction. Operand 0 is value to push. Used only when diff --git a/gcc/doc/objc.texi b/gcc/doc/objc.texi index dd04eda82f7..a36b0e70530 100644 --- a/gcc/doc/objc.texi +++ b/gcc/doc/objc.texi @@ -635,7 +635,8 @@ following class does this: + (void)initialize @{ - class_ivar_set_gcinvisible (self, "weakPointer", YES); + if (self == objc_lookUpClass ("WeakPointer")) + class_ivar_set_gcinvisible (self, "weakPointer", YES); @} - initWithPointer:(const void*)p diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 7143f0f1c92..90cef1c5f38 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -7530,18 +7530,6 @@ itself, by calling, for example, @code{output_operand_lossage}, it may just return @code{true}. @end deftypefn -@defmac OUTPUT_ADDR_CONST_EXTRA (@var{stream}, @var{x}, @var{fail}) -A C statement to recognize @var{rtx} patterns that -@code{output_addr_const} can't deal with, and output assembly code to -@var{stream} corresponding to the pattern @var{x}. This may be used to -allow machine-dependent @code{UNSPEC}s to appear within constants. - -If @code{OUTPUT_ADDR_CONST_EXTRA} fails to recognize a pattern, it must -@code{goto fail}, so that a standard error message is printed. If it -prints an error message itself, by calling, for example, -@code{output_operand_lossage}, it may just complete normally. -@end defmac - @defmac ASM_OUTPUT_ASCII (@var{stream}, @var{ptr}, @var{len}) A C statement to output to the stdio stream @var{stream} an assembler instruction to assemble a string constant containing the @var{len} diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index 67838269dff..187122eea81 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -7446,18 +7446,6 @@ itself, by calling, for example, @code{output_operand_lossage}, it may just return @code{true}. @end deftypefn -@defmac OUTPUT_ADDR_CONST_EXTRA (@var{stream}, @var{x}, @var{fail}) -A C statement to recognize @var{rtx} patterns that -@code{output_addr_const} can't deal with, and output assembly code to -@var{stream} corresponding to the pattern @var{x}. This may be used to -allow machine-dependent @code{UNSPEC}s to appear within constants. - -If @code{OUTPUT_ADDR_CONST_EXTRA} fails to recognize a pattern, it must -@code{goto fail}, so that a standard error message is printed. If it -prints an error message itself, by calling, for example, -@code{output_operand_lossage}, it may just complete normally. -@end defmac - @defmac ASM_OUTPUT_ASCII (@var{stream}, @var{ptr}, @var{len}) A C statement to output to the stdio stream @var{stream} an assembler instruction to assemble a string constant containing the @var{len} diff --git a/gcc/expr.c b/gcc/expr.c index d1807b0acc1..4ae61d7e8ad 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -8605,9 +8605,10 @@ expand_expr_real_2 (sepops ops, rtx target, enum machine_mode tmode, case VEC_PACK_FIX_TRUNC_EXPR: mode = TYPE_MODE (TREE_TYPE (treeop0)); goto binop; - - case VEC_SHUFFLE_EXPR: - target = expand_vec_shuffle_expr (type, treeop0, treeop1, treeop2, target); + + case VEC_PERM_EXPR: + target = expand_vec_perm_expr (type, treeop0, treeop1, treeop2, target); + gcc_assert (target); return target; case DOT_PROD_EXPR: diff --git a/gcc/fold-const.c b/gcc/fold-const.c index c3871f1075a..7568c6f143a 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -13647,7 +13647,7 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type, case BIT_FIELD_REF: if ((TREE_CODE (arg0) == VECTOR_CST - || (TREE_CODE (arg0) == CONSTRUCTOR && TREE_CONSTANT (arg0))) + || TREE_CODE (arg0) == CONSTRUCTOR) && type == TREE_TYPE (TREE_TYPE (arg0))) { unsigned HOST_WIDE_INT width = tree_low_cst (arg1, 1); @@ -13659,24 +13659,17 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type, && (idx = idx / width) < TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0))) { - tree elements = NULL_TREE; - if (TREE_CODE (arg0) == VECTOR_CST) - elements = TREE_VECTOR_CST_ELTS (arg0); - else { - unsigned HOST_WIDE_INT idx; - tree value; - - FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (arg0), idx, value) - elements = tree_cons (NULL_TREE, value, elements); + tree elements = TREE_VECTOR_CST_ELTS (arg0); + while (idx-- > 0 && elements) + elements = TREE_CHAIN (elements); + if (elements) + return TREE_VALUE (elements); } - while (idx-- > 0 && elements) - elements = TREE_CHAIN (elements); - if (elements) - return TREE_VALUE (elements); - else - return build_zero_cst (type); + else if (idx < CONSTRUCTOR_NELTS (arg0)) + return CONSTRUCTOR_ELT (arg0, idx)->value; + return build_zero_cst (type); } } @@ -13887,11 +13880,7 @@ fold_checksum_tree (const_tree expr, struct md5_ctx *ctx, htab_t ht) union tree_node buf; int i, len; -recursive_label: - - gcc_assert ((sizeof (struct tree_exp) + 5 * sizeof (tree) - <= sizeof (struct tree_function_decl)) - && sizeof (struct tree_type) <= sizeof (struct tree_function_decl)); + recursive_label: if (expr == NULL) return; slot = (void **) htab_find_slot (ht, expr, INSERT); diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 23053c41ae4..2156e716bdb 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,181 @@ +2011-10-09 Tobias Burnus <burnus@net-b.de> + + PR fortran/45044 + * trans-common.c (translate_common): Fix -Walign-commons check. + +2011-10-09 Mikael Morin <mikael.morin@sfr.fr> + + * interface.c (check_dummy_characteristics): Count dimensions starting + from one in diagnostic. + +2011-10-09 Tobias Burnus <burnus@net-b.de> + + * Make-lang.in (F95_PARSER_OBJS, GFORTRAN_TRANS_DEPS): Add + dependency on iso-c-binding.def and iso-fortran-env.def. + * module.c (import_iso_c_binding_module): Add error when + explicitly importing a nonstandard symbol; extend standard- + depending loading. + * iso-c-binding.def: Add c_float128 and c_float128_complex + integer parameters (for -std=gnu). + * intrinsic.texi (ISO_C_Binding): Document them. + * symbol.c (generate_isocbinding_symbol): Change macros + to ignore GFC_STD_* data. + * trans-types.c (gfc_init_c_interop_kinds): Ditto; make + nonstatic and renamed from "init_c_interop_kinds". + (gfc_init_kinds): Don't call it + * trans-types.h (gfc_init_c_interop_kinds): Add prototype. + * f95-lang.c (gfc_init_decl_processing): Call it. + +2011-10-09 Janus Weil <janus@gcc.gnu.org> + + PR fortran/50659 + * expr.c (replace_symbol): Only do replacement if the symbol is a dummy. + +2011-10-08 Paul Thomas <pault@gcc.gnu.org> + + PR fortran/47844 + * trans-array.c (gfc_conv_array_index_offset): Use descriptor + stride for pointer function results. + +2011-10-07 Mikael Morin <mikael.morin@sfr.fr> + + * trans-array.c (gfc_conv_expr_descriptor): Remove trailing whitespace. + +2011-10-07 Mikael Morin <mikael.morin@sfr.fr> + + * trans-array.c (gfc_conv_ss_startstride): Merge two switch cases. + +2011-10-07 Mikael Morin <mikael.morin@sfr.fr> + + * trans-array.c (gfc_conv_section_startstride): Remove coarray argument. + Remove conditions on coarray. + (gfc_conv_ss_startstride): Update call to gfc_conv_section_startstride. + (gfc_conv_expr_descriptor): Ditto. Add assertions before the call. + +2011-10-07 Mikael Morin <mikael.morin@sfr.fr> + + * trans-array.c (gfc_conv_section_startstride): Remove coarray_last + argument. Remove condition on coarray_last. + (gfc_conv_ss_startstride): Update call to gfc_conv_section_startstride. + (gfc_conv_expr_descriptor): Ditto. + +2011-10-07 Mikael Morin <mikael.morin@sfr.fr> + + * trans-array.c (gfc_walk_variable_expr): Remove scalar coarray + handling. Don't reset array ref's corank and codimensions' types + in the full array ref case. Update loop upper limit. + Remove DIMEN_THIS_IMAGE case. Remove unnecessary conditions. + +2011-10-07 Mikael Morin <mikael.morin@sfr.fr> + + * trans.h (gfc_ss_info): Remove codimen field. + * trans-array.c (gfc_get_array_ss): Don't set codimen field. + (gfc_trans_create_temp_array): Don't set descriptor's cobounds. + (gfc_trans_constant_array_constructor): Update loop upper limit. + (gfc_conv_ss_startstride): Don't set codimen field. + Don't get descriptor's cobounds. + (gfc_walk_variable_expr): Update dimension index. + * trans-intrinsic.c (trans_this_image, trans_image_index, + conv_intrinsic_cobound): Don't set codimen field + +2011-10-07 Mikael Morin <mikael.morin@sfr.fr> + + * trans.h (gfc_loopinfo): Remove codimen field. + * trans-array.c (gfc_set_vector_loop_bounds, + gfc_trans_scalarizing_loops, gfc_conv_loop_setup): Update loop upper + limit. + (gfc_set_loop_bounds_from_array_spec): Ditto. Remove skip on last + codimension. + (gfc_start_scalarized_body): Update loop lower limit. + (gfc_conv_ss_startstride): Don't set loop's codimen field. + (gfc_conv_loop_setup): Remove unnecessary condition. + (gfc_conv_expr_descriptor): Don't use loop's codimen field as corank. + +2011-10-07 Mikael Morin <mikael.morin@sfr.fr> + + * trans.h (gfc_ss): Remove data.temp.codimen field. + * trans-array.c (gfc_conv_resolve_dependencies, + gfc_conv_expr_descriptor): Don't set temp's codimen field. + +2011-10-07 Mikael Morin <mikael.morin@sfr.fr> + + * resolve.c (resolve_array_ref): Set array_ref's dimen field (and the + associated dimen_type) in the full array ref case. + +2011-10-07 Mikael Morin <mikael.morin@sfr.fr> + + * trans-intrinsic.c (walk_coarray): New function. + (convert_element_to_coarray_ref): Move code to walk_coarray. Remove. + (trans-this_image, trans_image_index, conv_intrinsic_cobound): + Use walk_coarray. + +2011-10-07 Mikael Morin <mikael.morin@sfr.fr> + + * trans-array.c (gfc_conv_expr_descriptor): Add out-of-the-scalarizer + cobounds evaluation. + +2011-10-07 Mikael Morin <mikael.morin@sfr.fr> + + * trans-array.c (gfc_conv_ss_startstride): Support zero rank loop. + +2011-10-07 Mikael Morin <mikael.morin@sfr.fr> + + * trans-array.c (gfc_conv_section_startstride): Move code to + evaluate_bound. Use evaluate_bound. + (evaluate_bound): New function. + +2011-10-07 Mikael Morin <mikael.morin@sfr.fr> + + * trans-array.c (gfc_conv_section_startstride): Update assertion to + also accept coarrays. + +2011-10-07 Mikael Morin <mikael.morin@sfr.fr> + + * trans-array.c (gfc_conv_section_startstride): Factor common + array ref references. + +2011-10-07 Mikael Morin <mikael.morin@sfr.fr> + + * trans-array.c (gfc_conv_expr_descriptor): Use codim instead of + loop.codimen as argument to gfc_get_array_type_bounds. + +2011-10-07 Mikael Morin <mikael.morin@sfr.fr> + + * trans-array.h (struct gfc_se): New flag want_coarray. + * trans-intrinsic.c (trans_this_image, trans_image_index, + conv_intrinsic_cobound): Set want_coarray. + * trans_array.c (gfc_conv_expr_descriptor): Evaluate codimension + earlier and without relying on the scalarizer. + +2011-10-07 Mikael Morin <mikael.morin@sfr.fr> + + * expr.c (gfc_get_corank): Return 0 if input expression is not a + coarray. + +2011-10-07 Mikael Morin <mikael.morin@sfr.fr> + + * trans-array.c (gfc_conv_expr_descriptor): Simplify coarray + descriptor setup code. + +2011-10-07 Mikael Morin <mikael.morin@sfr.fr> + + * resolve.c (compare_spec_to_ref): Move coarray ref initialization + code... + (resolve_array_ref): ... here. + +2011-10-07 Mikael Morin <mikael.morin@sfr.fr> + + * check.c (is_coarray): Remove. + (coarray_check): Use gfc_is_coarray. + +2011-10-07 Janus Weil <janus@gcc.gnu.org> + + PR fortran/50625 + * class.c (gfc_build_class_symbol): Fix whitespace. + * module.c (mio_symbol): Set 'class_ok' attribute. + * trans-decl.c (gfc_get_symbol_decl): Make sure the backend_decl has + been built for class symbols. + 2011-10-04 Janus Weil <janus@gcc.gnu.org> PR fortran/35831 @@ -207,7 +385,7 @@ * symbol.c (check_conflict): Allow threadprivate attribute with FL_PROCEDURE if proc_pointer. -2011-08-25 Mikael Morin <mikael.morin@gcc.gnu.org> +2011-08-25 Mikael Morin <mikael@gcc.gnu.org> PR fortran/50050 * expr.c (gfc_free_shape): Do nothing if shape is NULL. @@ -257,7 +435,7 @@ * cpp.c (gfc_cpp_init): Force BUILTINS_LOCATION for tokens defined in cpp_define_builtins. -2011-08-22 Mikael Morin <mikael.morin@gcc.gnu.org> +2011-08-22 Mikael Morin <mikael@gcc.gnu.org> PR fortran/50050 * gfortran.h (gfc_clear_shape, gfc_free_shape): New prototypes. diff --git a/gcc/fortran/ChangeLog-2008 b/gcc/fortran/ChangeLog-2008 index 7f536aa446c..6fe1eea164d 100644 --- a/gcc/fortran/ChangeLog-2008 +++ b/gcc/fortran/ChangeLog-2008 @@ -45,7 +45,7 @@ * trans-intrinsic.c (conv_same_strlen_check): New method. (gfc_conv_intrinsic_merge): Call it here to actually do the check. -2008-12-15 Mikael Morin <mikael.morin@tele2.fr> +2008-12-15 Mikael Morin <mikael@gcc.gnu.org> PR fortran/38487 * dependency.c (gfc_is_data_pointer): New function. @@ -53,7 +53,7 @@ in the pointer case. (gfc_check_dependency): Use gfc_is_data_pointer. -2008-12-15 Mikael Morin <mikael.morin@tele2.fr> +2008-12-15 Mikael Morin <mikael@gcc.gnu.org> PR fortran/38113 * error.c (show_locus): Start counting columns at 0. @@ -98,13 +98,13 @@ * invoke.texi (idirafter): New. (no-range-check): Fixed entry in option-index. -2008-12-09 Mikael Morin <mikael.morin@tele2.fr> +2008-12-09 Mikael Morin <mikael@gcc.gnu.org> PR fortran/37469 * expr.c (find_array_element): Simplify array bounds. Assert that both bounds are constant expressions. -2008-12-09 Mikael Morin <mikael.morin@tele2.fr> +2008-12-09 Mikael Morin <mikael@gcc.gnu.org> PR fortran/35983 * trans-expr.c (gfc_trans_subcomponent_assign): @@ -158,7 +158,7 @@ * trans-types.c (gfc_sym_type,gfc_get_function_type): Support procedure pointers as function result. -2008-12-01 Mikael Morin <mikael.morin@tele2.fr> +2008-12-01 Mikael Morin <mikael@gcc.gnu.org> PR fortran/38252 * parse.c (parse_spec): Skip statement order check in case @@ -193,7 +193,7 @@ * module.c (gfc_dump_module): Report error on unlink only if errno != ENOENT. -2008-11-25 Mikael Morin <mikael.morin@tele2.fr> +2008-11-25 Mikael Morin <mikael@gcc.gnu.org> PR fortran/36463 * expr.c (replace_symbol): Don't replace the symtree @@ -218,7 +218,7 @@ * arith.c (gfc_check_real_range): Add mpfr_check_range. * simplify.c (gfc_simplify_nearest): Add mpfr_check_range. -2008-11-24 Mikael Morin <mikael.morin@tele2.fr> +2008-11-24 Mikael Morin <mikael@gcc.gnu.org> PR fortran/38184 * simplify.c (is_constant_array_expr): Return true instead of false @@ -308,7 +308,7 @@ * module.c (load_equiv): Regression fix; check that equivalence members come from the same module only. -2008-11-16 Mikael Morin <mikael.morin@tele2.fr> +2008-11-16 Mikael Morin <mikael@gcc.gnu.org> PR fortran/35681 * dependency.c (gfc_check_argument_var_dependency): Add @@ -333,7 +333,7 @@ * dependency.h (enum gfc_dep_check): New enum. (gfc_check_fncall_dependency): Update prototype. -2008-11-16 Mikael Morin <mikael.morin@tele2.fr> +2008-11-16 Mikael Morin <mikael@gcc.gnu.org> PR fortran/37992 * gfortran.h (gfc_namespace): Added member old_cl_list, @@ -518,7 +518,7 @@ * fortran/check.c (gfc_check_random_seed): Check PUT size at compile time. -2008-10-31 Mikael Morin <mikael.morin@tele2.fr> +2008-10-31 Mikael Morin <mikael@gcc.gnu.org> PR fortran/35840 * expr.c (gfc_reduce_init_expr): New function, containing checking code @@ -528,7 +528,7 @@ checking that the expression is a constant. * match.h (gfc_reduce_init_expr): Prototype added. -2008-10-31 Mikael Morin <mikael.morin@tele2.fr> +2008-10-31 Mikael Morin <mikael@gcc.gnu.org> PR fortran/35820 * resolve.c (gfc_count_forall_iterators): New function. @@ -548,7 +548,7 @@ gfc_simplify_ifix, gfc_simplify_idint, simplify_nint): Update function calls to include locus. -2008-10-30 Mikael Morin <mikael.morin@tele2.fr> +2008-10-30 Mikael Morin <mikael@gcc.gnu.org> PR fortran/37903 * trans-array.c (gfc_trans_create_temp_array): If n is less @@ -563,7 +563,7 @@ possible. Calculate the translation from loop variables to array indices if an array constructor. -2008-10-30 Mikael Morin <mikael.morin@tele2.fr> +2008-10-30 Mikael Morin <mikael@gcc.gnu.org> PR fortran/37749 * trans-array.c (gfc_trans_create_temp_array): If size is NULL diff --git a/gcc/fortran/ChangeLog-2009 b/gcc/fortran/ChangeLog-2009 index 43d206a14b7..c5b7e621ba6 100644 --- a/gcc/fortran/ChangeLog-2009 +++ b/gcc/fortran/ChangeLog-2009 @@ -3519,7 +3519,7 @@ * intrinsic.texi (MALLOC): Make example more portable. -2009-02-13 Mikael Morin <mikael.morin@tele2.fr> +2009-02-13 Mikael Morin <mikael@gcc.gnu.org> PR fortran/38259 * module.c (gfc_dump_module,gfc_use_module): Add module @@ -3566,7 +3566,7 @@ * invoke.texi (RANGE): RANGE also takes INTEGER arguments. -2009-01-19 Mikael Morin <mikael.morin@tele2.fr> +2009-01-19 Mikael Morin <mikael@gcc.gnu.org> PR fortran/38859 * simplify.c (simplify_bound): Don't use array specification @@ -3656,7 +3656,7 @@ is substituted by a function. * resolve.c (check_host_association): Return if above is set. -2009-01-04 Mikael Morin <mikael.morin@tele2.fr> +2009-01-04 Mikael Morin <mikael@gcc.gnu.org> PR fortran/35681 * ChangeLog-2008: Fix function name. @@ -3681,7 +3681,7 @@ * intrinsic.h (gfc_simplify_merge): New prototype. * intrinsic.c (add_functions): Added simplification for MERGE. -2009-01-04 Mikael Morin <mikael.morin@tele2.fr> +2009-01-04 Mikael Morin <mikael@gcc.gnu.org> PR fortran/38536 * gfortran.h (gfc_is_data_pointer): Added prototype diff --git a/gcc/fortran/ChangeLog-2010 b/gcc/fortran/ChangeLog-2010 index 9110670693a..dc25cbd39b9 100644 --- a/gcc/fortran/ChangeLog-2010 +++ b/gcc/fortran/ChangeLog-2010 @@ -71,7 +71,7 @@ substring references. (gfc_check_same_strlen): Use gfc_var_strlen. -2010-12-23 Mikael Morin <mikael.morin@gcc.gnu.org> +2010-12-23 Mikael Morin <mikael@gcc.gnu.org> PR fortran/46978 Revert part of revision 164112 diff --git a/gcc/fortran/Make-lang.in b/gcc/fortran/Make-lang.in index 08164587d0b..b766da651a2 100644 --- a/gcc/fortran/Make-lang.in +++ b/gcc/fortran/Make-lang.in @@ -329,14 +329,16 @@ $(F95_PARSER_OBJS): fortran/gfortran.h fortran/libgfortran.h \ fortran/parse.h fortran/arith.h fortran/target-memory.h \ $(CONFIG_H) $(SYSTEM_H) $(TM_H) $(TM_P_H) coretypes.h \ $(RTL_H) $(TREE_H) $(TREE_DUMP_H) $(GGC_H) $(EXPR_H) \ - $(FLAGS_H) output.h $(DIAGNOSTIC_H) errors.h $(FUNCTION_H) + $(FLAGS_H) output.h $(DIAGNOSTIC_H) errors.h $(FUNCTION_H) \ + fortran/iso-c-binding.def fortran/iso-fortran-env.def fortran/openmp.o: pointer-set.h $(TARGET_H) toplev.h GFORTRAN_TRANS_DEPS = fortran/gfortran.h fortran/libgfortran.h \ fortran/intrinsic.h fortran/trans-array.h \ fortran/trans-const.h fortran/trans-const.h fortran/trans.h \ fortran/trans-stmt.h fortran/trans-types.h \ - $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(TM_H) coretypes.h $(GGC_H) + $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(TM_H) coretypes.h $(GGC_H) \ + fortran/iso-c-binding.def fortran/iso-fortran-env.def fortran/f95-lang.o: $(GFORTRAN_TRANS_DEPS) fortran/mathbuiltins.def \ gt-fortran-f95-lang.h gtype-fortran.h $(CGRAPH_H) $(TARGET_H) fortran/cpp.h \ diff --git a/gcc/fortran/check.c b/gcc/fortran/check.c index b1fc38accb8..9b8ec21a763 100644 --- a/gcc/fortran/check.c +++ b/gcc/fortran/check.c @@ -203,42 +203,10 @@ double_check (gfc_expr *d, int n) } -/* Check whether an expression is a coarray (without array designator). */ - -static bool -is_coarray (gfc_expr *e) -{ - bool coarray = false; - gfc_ref *ref; - - if (e->expr_type != EXPR_VARIABLE) - return false; - - coarray = e->symtree->n.sym->attr.codimension; - - for (ref = e->ref; ref; ref = ref->next) - { - if (ref->type == REF_COMPONENT) - coarray = ref->u.c.component->attr.codimension; - else if (ref->type != REF_ARRAY || ref->u.ar.dimen != 0) - coarray = false; - else if (ref->type == REF_ARRAY && ref->u.ar.codimen != 0) - { - int n; - for (n = 0; n < ref->u.ar.codimen; n++) - if (ref->u.ar.dimen_type[n] != DIMEN_THIS_IMAGE) - coarray = false; - } - } - - return coarray; -} - - static gfc_try coarray_check (gfc_expr *e, int n) { - if (!is_coarray (e)) + if (!gfc_is_coarray (e)) { gfc_error ("Expected coarray variable as '%s' argument to the %s " "intrinsic at %L", gfc_current_intrinsic_arg[n]->name, diff --git a/gcc/fortran/class.c b/gcc/fortran/class.c index 572011f45f6..f64cc1b2a81 100644 --- a/gcc/fortran/class.c +++ b/gcc/fortran/class.c @@ -188,7 +188,7 @@ gfc_build_class_symbol (gfc_typespec *ts, symbol_attribute *attr, /* Class container has already been built. */ return SUCCESS; - attr->class_ok = attr->dummy || attr->pointer || attr->allocatable; + attr->class_ok = attr->dummy || attr->pointer || attr->allocatable; if (!attr->class_ok) /* We can not build the class container yet. */ diff --git a/gcc/fortran/expr.c b/gcc/fortran/expr.c index 813a99d037b..8a09a28b289 100644 --- a/gcc/fortran/expr.c +++ b/gcc/fortran/expr.c @@ -4134,8 +4134,9 @@ gfc_expr_check_typed (gfc_expr* e, gfc_namespace* ns, bool strict) return error_found ? FAILURE : SUCCESS; } -/* Walk an expression tree and replace all symbols with a corresponding symbol - in the formal_ns of "sym". Needed for copying interfaces in PROCEDURE + +/* Walk an expression tree and replace all dummy symbols by the corresponding + symbol in the formal_ns of "sym". Needed for copying interfaces in PROCEDURE statements. The boolean return value is required by gfc_traverse_expr. */ static bool @@ -4144,14 +4145,12 @@ replace_symbol (gfc_expr *expr, gfc_symbol *sym, int *i ATTRIBUTE_UNUSED) if ((expr->expr_type == EXPR_VARIABLE || (expr->expr_type == EXPR_FUNCTION && !gfc_is_intrinsic (expr->symtree->n.sym, 0, expr->where))) - && expr->symtree->n.sym->ns == sym->ts.interface->formal_ns) + && expr->symtree->n.sym->ns == sym->ts.interface->formal_ns + && expr->symtree->n.sym->attr.dummy) { - gfc_symtree *stree; - gfc_namespace *ns = sym->formal_ns; - /* Don't use gfc_get_symtree as we prefer to fail badly if we don't find - the symtree rather than create a new one (and probably fail later). */ - stree = gfc_find_symtree (ns ? ns->sym_root : gfc_current_ns->sym_root, - expr->symtree->n.sym->name); + gfc_symtree *root = sym->formal_ns ? sym->formal_ns->sym_root + : gfc_current_ns->sym_root; + gfc_symtree *stree = gfc_find_symtree (root, expr->symtree->n.sym->name); gcc_assert (stree); stree->n.sym->attr = expr->symtree->n.sym->attr; expr->symtree = stree; @@ -4165,6 +4164,7 @@ gfc_expr_replace_symbols (gfc_expr *expr, gfc_symbol *dest) gfc_traverse_expr (expr, dest, &replace_symbol, 0); } + /* The following is analogous to 'replace_symbol', and needed for copying interfaces for procedure pointer components. The argument 'sym' must formally be a gfc_symbol, so that the function can be passed to gfc_traverse_expr. @@ -4301,13 +4301,19 @@ gfc_get_corank (gfc_expr *e) { int corank; gfc_ref *ref; + + if (!gfc_is_coarray (e)) + return 0; + corank = e->symtree->n.sym->as ? e->symtree->n.sym->as->corank : 0; + for (ref = e->ref; ref; ref = ref->next) { if (ref->type == REF_ARRAY) corank = ref->u.ar.as->corank; gcc_assert (ref->type != REF_SUBSTRING); } + return corank; } diff --git a/gcc/fortran/f95-lang.c b/gcc/fortran/f95-lang.c index 648831f2607..8f8dd7d4c35 100644 --- a/gcc/fortran/f95-lang.c +++ b/gcc/fortran/f95-lang.c @@ -595,6 +595,7 @@ gfc_init_decl_processing (void) /* Set up F95 type nodes. */ gfc_init_kinds (); gfc_init_types (); + gfc_init_c_interop_kinds (); } diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index 54e0b20580d..1bd5ec36edd 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -610,8 +610,8 @@ iso_fortran_env_symbol; #undef NAMED_DERIVED_TYPE #define NAMED_INTCST(a,b,c,d) a, -#define NAMED_REALCST(a,b,c) a, -#define NAMED_CMPXCST(a,b,c) a, +#define NAMED_REALCST(a,b,c,d) a, +#define NAMED_CMPXCST(a,b,c,d) a, #define NAMED_LOGCST(a,b,c) a, #define NAMED_CHARKNDCST(a,b,c) a, #define NAMED_CHARCST(a,b,c) a, diff --git a/gcc/fortran/interface.c b/gcc/fortran/interface.c index 43b911376f5..5308513b774 100644 --- a/gcc/fortran/interface.c +++ b/gcc/fortran/interface.c @@ -1098,7 +1098,7 @@ check_dummy_characteristics (gfc_symbol *s1, gfc_symbol *s2, case 1: case -3: snprintf (errmsg, err_len, "Shape mismatch in dimension %i of " - "argument '%s'", i, s1->name); + "argument '%s'", i + 1, s1->name); return FAILURE; case -2: diff --git a/gcc/fortran/intrinsic.texi b/gcc/fortran/intrinsic.texi index 9adeeabf60d..a093bec8c7c 100644 --- a/gcc/fortran/intrinsic.texi +++ b/gcc/fortran/intrinsic.texi @@ -13006,7 +13006,9 @@ type default integer, which can be used as KIND type parameters. In addition to the integer named constants required by the Fortran 2003 standard, GNU Fortran provides as an extension named constants for the 128-bit integer types supported by the C compiler: @code{C_INT128_T, -C_INT_LEAST128_T, C_INT_FAST128_T}. +C_INT_LEAST128_T, C_INT_FAST128_T}. Furthermore, if @code{__float} is +supported in C, the named constants @code{C_FLOAT128, C_FLOAT128_COMPLEX} +are defined. @multitable @columnfractions .15 .35 .35 .35 @item Fortran Type @tab Named constant @tab C type @tab Extension @@ -13036,9 +13038,11 @@ C_INT_LEAST128_T, C_INT_FAST128_T}. @item @code{REAL} @tab @code{C_FLOAT} @tab @code{float} @item @code{REAL} @tab @code{C_DOUBLE} @tab @code{double} @item @code{REAL} @tab @code{C_LONG_DOUBLE} @tab @code{long double} +@item @code{REAL} @tab @code{C_FLOAT128} @tab @code{__float128} @tab Ext. @item @code{COMPLEX}@tab @code{C_FLOAT_COMPLEX} @tab @code{float _Complex} @item @code{COMPLEX}@tab @code{C_DOUBLE_COMPLEX}@tab @code{double _Complex} @item @code{COMPLEX}@tab @code{C_LONG_DOUBLE_COMPLEX}@tab @code{long double _Complex} +@item @code{REAL} @tab @code{C_FLOAT128_COMPLEX} @tab @code{__float128 _Complex} @tab Ext. @item @code{LOGICAL}@tab @code{C_BOOL} @tab @code{_Bool} @item @code{CHARACTER}@tab @code{C_CHAR} @tab @code{char} @end multitable diff --git a/gcc/fortran/iso-c-binding.def b/gcc/fortran/iso-c-binding.def index bea83067bfe..f8673b963c8 100644 --- a/gcc/fortran/iso-c-binding.def +++ b/gcc/fortran/iso-c-binding.def @@ -24,11 +24,11 @@ along with GCC; see the file COPYING3. If not see #endif #ifndef NAMED_REALCST -# define NAMED_REALCST(a,b,c) +# define NAMED_REALCST(a,b,c,d) #endif #ifndef NAMED_CMPXCST -# define NAMED_CMPXCST(a,b,c) +# define NAMED_CMPXCST(a,b,c,d) #endif #ifndef NAMED_LOGCST @@ -103,17 +103,25 @@ NAMED_INTCST (ISOCBINDING_INT_FAST128_T, "c_int_fast128_t", get_int_kind_from_width (128), GFC_STD_GNU) NAMED_REALCST (ISOCBINDING_FLOAT, "c_float", \ - get_real_kind_from_node (float_type_node)) + get_real_kind_from_node (float_type_node), GFC_STD_F2003) NAMED_REALCST (ISOCBINDING_DOUBLE, "c_double", \ - get_real_kind_from_node (double_type_node)) + get_real_kind_from_node (double_type_node), GFC_STD_F2003) NAMED_REALCST (ISOCBINDING_LONG_DOUBLE, "c_long_double", \ - get_real_kind_from_node (long_double_type_node)) + get_real_kind_from_node (long_double_type_node), GFC_STD_F2003) +NAMED_REALCST (ISOCBINDING_FLOAT128, "c_float128", \ + float128_type_node == NULL_TREE \ + ? -4 : get_real_kind_from_node (float128_type_node), \ + GFC_STD_GNU) NAMED_CMPXCST (ISOCBINDING_FLOAT_COMPLEX, "c_float_complex", \ - get_real_kind_from_node (float_type_node)) + get_real_kind_from_node (float_type_node), GFC_STD_F2003) NAMED_CMPXCST (ISOCBINDING_DOUBLE_COMPLEX, "c_double_complex", \ - get_real_kind_from_node (double_type_node)) + get_real_kind_from_node (double_type_node), GFC_STD_F2003) NAMED_CMPXCST (ISOCBINDING_LONG_DOUBLE_COMPLEX, "c_long_double_complex", \ - get_real_kind_from_node (long_double_type_node)) + get_real_kind_from_node (long_double_type_node), GFC_STD_F2003) +NAMED_CMPXCST (ISOCBINDING_FLOAT128_COMPLEX, "c_float128_complex", \ + float128_type_node == NULL_TREE \ + ? -4 : get_real_kind_from_node (float128_type_node), \ + GFC_STD_GNU) NAMED_LOGCST (ISOCBINDING_BOOL, "c_bool", \ get_int_kind_from_width (BOOL_TYPE_SIZE)) diff --git a/gcc/fortran/module.c b/gcc/fortran/module.c index b29ba4b66ee..62f759876d3 100644 --- a/gcc/fortran/module.c +++ b/gcc/fortran/module.c @@ -3608,6 +3608,8 @@ mio_symbol (gfc_symbol *sym) mio_symbol_attribute (&sym->attr); mio_typespec (&sym->ts); + if (sym->ts.type == BT_CLASS) + sym->attr.class_ok = 1; if (iomode == IO_OUTPUT) mio_namespace_ref (&sym->formal_ns); @@ -5348,8 +5350,53 @@ import_iso_c_binding_module (void) for (u = gfc_rename_list; u; u = u->next) if (strcmp (c_interop_kinds_table[i].name, u->use_name) == 0) { + bool not_in_std; + const char *name; u->found = 1; found = true; + + switch (i) + { +#define NAMED_FUNCTION(a,b,c,d) \ + case a: \ + not_in_std = (gfc_option.allow_std & d) == 0; \ + name = b; \ + break; +#include "iso-c-binding.def" +#undef NAMED_FUNCTION +#define NAMED_INTCST(a,b,c,d) \ + case a: \ + not_in_std = (gfc_option.allow_std & d) == 0; \ + name = b; \ + break; +#include "iso-c-binding.def" +#undef NAMED_INTCST +#define NAMED_REALCST(a,b,c,d) \ + case a: \ + not_in_std = (gfc_option.allow_std & d) == 0; \ + name = b; \ + break; +#include "iso-c-binding.def" +#undef NAMED_REALCST +#define NAMED_CMPXCST(a,b,c,d) \ + case a: \ + not_in_std = (gfc_option.allow_std & d) == 0; \ + name = b; \ + break; +#include "iso-c-binding.def" +#undef NAMED_CMPXCST + default: + not_in_std = false; + name = ""; + } + + if (not_in_std) + { + gfc_error ("The symbol '%s', referenced at %C, is not " + "in the selected standard", name); + continue; + } + switch (i) { #define NAMED_FUNCTION(a,b,c,d) \ @@ -5372,23 +5419,59 @@ import_iso_c_binding_module (void) } if (!found && !only_flag) - switch (i) - { + { + /* Skip, if the symbol is not in the enabled standard. */ + switch (i) + { +#define NAMED_FUNCTION(a,b,c,d) \ + case a: \ + if ((gfc_option.allow_std & d) == 0) \ + continue; \ + break; +#include "iso-c-binding.def" +#undef NAMED_FUNCTION + +#define NAMED_INTCST(a,b,c,d) \ + case a: \ + if ((gfc_option.allow_std & d) == 0) \ + continue; \ + break; +#include "iso-c-binding.def" +#undef NAMED_INTCST +#define NAMED_REALCST(a,b,c,d) \ + case a: \ + if ((gfc_option.allow_std & d) == 0) \ + continue; \ + break; +#include "iso-c-binding.def" +#undef NAMED_REALCST +#define NAMED_CMPXCST(a,b,c,d) \ + case a: \ + if ((gfc_option.allow_std & d) == 0) \ + continue; \ + break; +#include "iso-c-binding.def" +#undef NAMED_CMPXCST + default: + ; /* Not GFC_STD_* versioned. */ + } + + switch (i) + { #define NAMED_FUNCTION(a,b,c,d) \ - case a: \ - if ((gfc_option.allow_std & d) == 0) \ - continue; \ - create_intrinsic_function (b, (gfc_isym_id) c, \ - iso_c_module_name, \ - INTMOD_ISO_C_BINDING); \ + case a: \ + create_intrinsic_function (b, (gfc_isym_id) c, \ + iso_c_module_name, \ + INTMOD_ISO_C_BINDING); \ break; #include "iso-c-binding.def" #undef NAMED_FUNCTION - default: - generate_isocbinding_symbol (iso_c_module_name, - (iso_c_binding_symbol) i, NULL); - } + default: + generate_isocbinding_symbol (iso_c_module_name, + (iso_c_binding_symbol) i, NULL); + } + } } for (u = gfc_rename_list; u; u = u->next) diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c index 84db3ddb019..edeb49daf7d 100644 --- a/gcc/fortran/resolve.c +++ b/gcc/fortran/resolve.c @@ -4396,14 +4396,6 @@ compare_spec_to_ref (gfc_array_ref *ar) return FAILURE; } - if (as->corank && ar->codimen == 0) - { - int n; - ar->codimen = as->corank; - for (n = ar->dimen; n < ar->dimen + ar->codimen; n++) - ar->dimen_type[n] = DIMEN_THIS_IMAGE; - } - return SUCCESS; } @@ -4652,8 +4644,23 @@ resolve_array_ref (gfc_array_ref *ar) } } - if (ar->type == AR_FULL && ar->as->rank == 0) - ar->type = AR_ELEMENT; + if (ar->type == AR_FULL) + { + if (ar->as->rank == 0) + ar->type = AR_ELEMENT; + + /* Make sure array is the same as array(:,:), this way + we don't need to special case all the time. */ + ar->dimen = ar->as->rank; + for (i = 0; i < ar->dimen; i++) + { + ar->dimen_type[i] = DIMEN_RANGE; + + gcc_assert (ar->start[i] == NULL); + gcc_assert (ar->end[i] == NULL); + gcc_assert (ar->stride[i] == NULL); + } + } /* If the reference type is unknown, figure out what kind it is. */ @@ -4672,6 +4679,14 @@ resolve_array_ref (gfc_array_ref *ar) if (!ar->as->cray_pointee && compare_spec_to_ref (ar) == FAILURE) return FAILURE; + if (ar->as->corank && ar->codimen == 0) + { + int n; + ar->codimen = ar->as->corank; + for (n = ar->dimen; n < ar->dimen + ar->codimen; n++) + ar->dimen_type[n] = DIMEN_THIS_IMAGE; + } + return SUCCESS; } diff --git a/gcc/fortran/symbol.c b/gcc/fortran/symbol.c index 46eccb46aba..4b506fe83e8 100644 --- a/gcc/fortran/symbol.c +++ b/gcc/fortran/symbol.c @@ -4336,8 +4336,8 @@ generate_isocbinding_symbol (const char *mod_name, iso_c_binding_symbol s, { #define NAMED_INTCST(a,b,c,d) case a : -#define NAMED_REALCST(a,b,c) case a : -#define NAMED_CMPXCST(a,b,c) case a : +#define NAMED_REALCST(a,b,c,d) case a : +#define NAMED_CMPXCST(a,b,c,d) case a : #define NAMED_LOGCST(a,b,c) case a : #define NAMED_CHARKNDCST(a,b,c) case a : #include "iso-c-binding.def" diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c index 37cdeb560ee..b7556704ca1 100644 --- a/gcc/fortran/trans-array.c +++ b/gcc/fortran/trans-array.c @@ -526,7 +526,6 @@ gfc_get_array_ss (gfc_ss *next, gfc_expr *expr, int dimen, gfc_ss_type type) ss->expr = expr; info = &ss->data.info; info->dimen = dimen; - info->codimen = 0; for (i = 0; i < info->dimen; i++) info->dim[i] = i; @@ -641,7 +640,7 @@ gfc_set_loop_bounds_from_array_spec (gfc_interface_mapping * mapping, tree tmp; if (as && as->type == AS_EXPLICIT) - for (n = 0; n < se->loop->dimen + se->loop->codimen; n++) + for (n = 0; n < se->loop->dimen; n++) { dim = se->ss->data.info.dim[n]; gcc_assert (dim < as->rank); @@ -655,22 +654,18 @@ gfc_set_loop_bounds_from_array_spec (gfc_interface_mapping * mapping, gfc_add_block_to_block (&se->post, &tmpse.post); lower = fold_convert (gfc_array_index_type, tmpse.expr); - if (se->loop->codimen == 0 - || n < se->loop->dimen + se->loop->codimen - 1) - { - /* ...and the upper bound. */ - gfc_init_se (&tmpse, NULL); - gfc_apply_interface_mapping (mapping, &tmpse, as->upper[dim]); - gfc_add_block_to_block (&se->pre, &tmpse.pre); - gfc_add_block_to_block (&se->post, &tmpse.post); - upper = fold_convert (gfc_array_index_type, tmpse.expr); - - /* Set the upper bound of the loop to UPPER - LOWER. */ - tmp = fold_build2_loc (input_location, MINUS_EXPR, - gfc_array_index_type, upper, lower); - tmp = gfc_evaluate_now (tmp, &se->pre); - se->loop->to[n] = tmp; - } + /* ...and the upper bound. */ + gfc_init_se (&tmpse, NULL); + gfc_apply_interface_mapping (mapping, &tmpse, as->upper[dim]); + gfc_add_block_to_block (&se->pre, &tmpse.pre); + gfc_add_block_to_block (&se->post, &tmpse.post); + upper = fold_convert (gfc_array_index_type, tmpse.expr); + + /* Set the upper bound of the loop to UPPER - LOWER. */ + tmp = fold_build2_loc (input_location, MINUS_EXPR, + gfc_array_index_type, upper, lower); + tmp = gfc_evaluate_now (tmp, &se->pre); + se->loop->to[n] = tmp; } } } @@ -977,13 +972,6 @@ gfc_trans_create_temp_array (stmtblock_t * pre, stmtblock_t * post, size, tmp); size = gfc_evaluate_now (size, pre); } - for (n = info->dimen; n < info->dimen + info->codimen; n++) - { - gfc_conv_descriptor_lbound_set (pre, desc, gfc_rank_cst[n], - gfc_index_zero_node); - if (n < info->dimen + info->codimen - 1) - gfc_conv_descriptor_ubound_set (pre, desc, gfc_rank_cst[n], loop->to[n]); - } /* Get the size of the array. */ @@ -1876,7 +1864,7 @@ gfc_trans_constant_array_constructor (gfc_loopinfo * loop, info->data = gfc_build_addr_expr (NULL_TREE, tmp); info->offset = gfc_index_zero_node; - for (i = 0; i < info->dimen + info->codimen; i++) + for (i = 0; i < info->dimen; i++) { info->delta[i] = gfc_index_zero_node; info->start[i] = gfc_index_zero_node; @@ -2116,7 +2104,7 @@ gfc_set_vector_loop_bounds (gfc_loopinfo * loop, gfc_ss_info * info) int n; int dim; - for (n = 0; n < loop->dimen + loop->codimen; n++) + for (n = 0; n < loop->dimen; n++) { dim = info->dim[n]; if (info->ref->u.ar.dimen_type[dim] == DIMEN_VECTOR @@ -2621,6 +2609,18 @@ gfc_conv_array_index_offset (gfc_se * se, gfc_ss_info * info, int dim, int i, /* Temporary array or derived type component. */ gcc_assert (se->loop); index = se->loop->loopvar[se->loop->order[i]]; + + /* Pointer functions can have stride[0] different from unity. + Use the stride returned by the function call and stored in + the descriptor for the temporary. */ + if (se->ss && se->ss->type == GFC_SS_FUNCTION + && se->ss->expr + && se->ss->expr->symtree + && se->ss->expr->symtree->n.sym->result + && se->ss->expr->symtree->n.sym->result->attr.pointer) + stride = gfc_conv_descriptor_stride_get (info->descriptor, + gfc_rank_cst[dim]); + if (!integer_zerop (info->delta[dim])) index = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type, index, info->delta[dim]); @@ -2948,7 +2948,7 @@ gfc_start_scalarized_body (gfc_loopinfo * loop, stmtblock_t * pbody) gcc_assert (!loop->array_parameter); - for (dim = loop->dimen + loop->codimen - 1; dim >= 0; dim--) + for (dim = loop->dimen - 1; dim >= 0; dim--) { n = loop->order[dim]; @@ -3102,7 +3102,7 @@ gfc_trans_scalarizing_loops (gfc_loopinfo * loop, stmtblock_t * body) pblock = body; /* Generate the loops. */ - for (dim = 0; dim < loop->dimen + loop->codimen; dim++) + for (dim = 0; dim < loop->dimen; dim++) { n = loop->order[dim]; gfc_trans_scalarized_loop_end (loop, n, pblock); @@ -3175,82 +3175,83 @@ gfc_trans_scalarized_loop_boundary (gfc_loopinfo * loop, stmtblock_t * body) } +/* Precalculate (either lower or upper) bound of an array section. + BLOCK: Block in which the (pre)calculation code will go. + BOUNDS[DIM]: Where the bound value will be stored once evaluated. + VALUES[DIM]: Specified bound (NULL <=> unspecified). + DESC: Array descriptor from which the bound will be picked if unspecified + (either lower or upper bound according to LBOUND). */ + +static void +evaluate_bound (stmtblock_t *block, tree *bounds, gfc_expr ** values, + tree desc, int dim, bool lbound) +{ + gfc_se se; + gfc_expr * input_val = values[dim]; + tree *output = &bounds[dim]; + + + if (input_val) + { + /* Specified section bound. */ + gfc_init_se (&se, NULL); + gfc_conv_expr_type (&se, input_val, gfc_array_index_type); + gfc_add_block_to_block (block, &se.pre); + *output = se.expr; + } + else + { + /* No specific bound specified so use the bound of the array. */ + *output = lbound ? gfc_conv_array_lbound (desc, dim) : + gfc_conv_array_ubound (desc, dim); + } + *output = gfc_evaluate_now (*output, block); +} + + /* Calculate the lower bound of an array section. */ static void -gfc_conv_section_startstride (gfc_loopinfo * loop, gfc_ss * ss, int dim, - bool coarray, bool coarray_last) +gfc_conv_section_startstride (gfc_loopinfo * loop, gfc_ss * ss, int dim) { - gfc_expr *start; - gfc_expr *end; gfc_expr *stride = NULL; tree desc; gfc_se se; gfc_ss_info *info; + gfc_array_ref *ar; gcc_assert (ss->type == GFC_SS_SECTION); info = &ss->data.info; + ar = &info->ref->u.ar; - if (info->ref->u.ar.dimen_type[dim] == DIMEN_VECTOR) + if (ar->dimen_type[dim] == DIMEN_VECTOR) { /* We use a zero-based index to access the vector. */ info->start[dim] = gfc_index_zero_node; info->end[dim] = NULL; - if (!coarray) - info->stride[dim] = gfc_index_one_node; + info->stride[dim] = gfc_index_one_node; return; } - gcc_assert (info->ref->u.ar.dimen_type[dim] == DIMEN_RANGE); + gcc_assert (ar->dimen_type[dim] == DIMEN_RANGE + || ar->dimen_type[dim] == DIMEN_THIS_IMAGE); desc = info->descriptor; - start = info->ref->u.ar.start[dim]; - end = info->ref->u.ar.end[dim]; - if (!coarray) - stride = info->ref->u.ar.stride[dim]; + stride = ar->stride[dim]; /* Calculate the start of the range. For vector subscripts this will be the range of the vector. */ - if (start) - { - /* Specified section start. */ - gfc_init_se (&se, NULL); - gfc_conv_expr_type (&se, start, gfc_array_index_type); - gfc_add_block_to_block (&loop->pre, &se.pre); - info->start[dim] = se.expr; - } - else - { - /* No lower bound specified so use the bound of the array. */ - info->start[dim] = gfc_conv_array_lbound (desc, dim); - } - info->start[dim] = gfc_evaluate_now (info->start[dim], &loop->pre); + evaluate_bound (&loop->pre, info->start, ar->start, desc, dim, true); /* Similarly calculate the end. Although this is not used in the scalarizer, it is needed when checking bounds and where the end is an expression with side-effects. */ - if (!coarray_last) - { - if (end) - { - /* Specified section start. */ - gfc_init_se (&se, NULL); - gfc_conv_expr_type (&se, end, gfc_array_index_type); - gfc_add_block_to_block (&loop->pre, &se.pre); - info->end[dim] = se.expr; - } - else - { - /* No upper bound specified so use the bound of the array. */ - info->end[dim] = gfc_conv_array_ubound (desc, dim); - } - info->end[dim] = gfc_evaluate_now (info->end[dim], &loop->pre); - } + evaluate_bound (&loop->pre, info->end, ar->end, desc, dim, false); /* Calculate the stride. */ - if (!coarray && stride == NULL) + if (stride == NULL) info->stride[dim] = gfc_index_one_node; - else if (!coarray) + else { gfc_init_se (&se, NULL); gfc_conv_expr_type (&se, stride, gfc_array_index_type); @@ -3274,8 +3275,7 @@ gfc_conv_ss_startstride (gfc_loopinfo * loop) loop->dimen = 0; /* Determine the rank of the loop. */ - for (ss = loop->ss; - ss != gfc_ss_terminator && loop->dimen == 0; ss = ss->loop_chain) + for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain) { switch (ss->type) { @@ -3284,8 +3284,7 @@ gfc_conv_ss_startstride (gfc_loopinfo * loop) case GFC_SS_FUNCTION: case GFC_SS_COMPONENT: loop->dimen = ss->data.info.dimen; - loop->codimen = ss->data.info.codimen; - break; + goto done; /* As usual, lbound and ubound are exceptions!. */ case GFC_SS_INTRINSIC: @@ -3293,16 +3292,11 @@ gfc_conv_ss_startstride (gfc_loopinfo * loop) { case GFC_ISYM_LBOUND: case GFC_ISYM_UBOUND: - loop->dimen = ss->data.info.dimen; - loop->codimen = 0; - break; - case GFC_ISYM_LCOBOUND: case GFC_ISYM_UCOBOUND: case GFC_ISYM_THIS_IMAGE: loop->dimen = ss->data.info.dimen; - loop->codimen = ss->data.info.codimen; - break; + goto done; default: break; @@ -3315,8 +3309,9 @@ gfc_conv_ss_startstride (gfc_loopinfo * loop) /* We should have determined the rank of the expression by now. If not, that's bad news. */ - gcc_assert (loop->dimen + loop->codimen != 0); + gcc_unreachable (); +done: /* Loop over all the SS in the chain. */ for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain) { @@ -3330,14 +3325,7 @@ gfc_conv_ss_startstride (gfc_loopinfo * loop) gfc_conv_ss_descriptor (&loop->pre, ss, !loop->array_parameter); for (n = 0; n < ss->data.info.dimen; n++) - gfc_conv_section_startstride (loop, ss, ss->data.info.dim[n], - false, false); - for (n = ss->data.info.dimen; - n < ss->data.info.dimen + ss->data.info.codimen; n++) - gfc_conv_section_startstride (loop, ss, ss->data.info.dim[n], true, - n == ss->data.info.dimen - + ss->data.info.codimen -1); - + gfc_conv_section_startstride (loop, ss, ss->data.info.dim[n]); break; case GFC_SS_INTRINSIC: @@ -3856,7 +3844,6 @@ temporary: base_type = gfc_get_element_type (base_type); loop->temp_ss = gfc_get_temp_ss (base_type, dest->string_length, loop->dimen); - loop->temp_ss->data.temp.codimen = loop->codimen; gfc_add_ss_to_loop (loop, loop->temp_ss); } else @@ -3884,7 +3871,7 @@ gfc_conv_loop_setup (gfc_loopinfo * loop, locus * where) mpz_t i; mpz_init (i); - for (n = 0; n < loop->dimen + loop->codimen; n++) + for (n = 0; n < loop->dimen; n++) { loopspec[n] = NULL; dynamic[n] = false; @@ -3993,7 +3980,7 @@ gfc_conv_loop_setup (gfc_loopinfo * loop, locus * where) /* Set the extents of this range. */ cshape = loopspec[n]->shape; - if (n < loop->dimen && cshape && INTEGER_CST_P (info->start[dim]) + if (cshape && INTEGER_CST_P (info->start[dim]) && INTEGER_CST_P (info->stride[dim])) { loop->from[n] = info->start[dim]; @@ -5915,7 +5902,6 @@ gfc_conv_expr_descriptor (gfc_se * se, gfc_expr * expr, gfc_ss * ss) se->string_length = loop.temp_ss->string_length; gcc_assert (loop.temp_ss->data.temp.dimen == loop.dimen); - loop.temp_ss->data.temp.codimen = loop.codimen; gfc_add_ss_to_loop (&loop, loop.temp_ss); } @@ -5988,6 +5974,32 @@ gfc_conv_expr_descriptor (gfc_se * se, gfc_expr * expr, gfc_ss * ss) tree to; tree base; + if (se->want_coarray) + { + codim = gfc_get_corank (expr); + for (n = ss->data.info.dimen; n < ss->data.info.dimen + codim - 1; + n++) + { + /* Make sure we are not lost somehow. */ + gcc_assert (info->ref->u.ar.dimen_type[n] == DIMEN_THIS_IMAGE); + + /* Make sure the call to gfc_conv_section_startstride won't + generate unnecessary code to calculate stride. */ + gcc_assert (info->ref->u.ar.stride[n] == NULL); + + gfc_conv_section_startstride (&loop, ss, n); + loop.from[n] = info->start[n]; + loop.to[n] = info->end[n]; + } + + gcc_assert (n == ss->data.info.dimen + codim - 1); + evaluate_bound (&loop.pre, info->start, info->ref->u.ar.start, + info->descriptor, n, true); + loop.from[n] = info->start[n]; + } + else + codim = 0; + /* Set the string_length for a character array. */ if (expr->ts.type == BT_CHARACTER) se->string_length = gfc_get_expr_charlen (expr); @@ -6003,9 +6015,8 @@ gfc_conv_expr_descriptor (gfc_se * se, gfc_expr * expr, gfc_ss * ss) { /* Otherwise make a new one. */ parmtype = gfc_get_element_type (TREE_TYPE (desc)); - parmtype = gfc_get_array_type_bounds (parmtype, loop.dimen, - loop.codimen, loop.from, - loop.to, 0, + parmtype = gfc_get_array_type_bounds (parmtype, loop.dimen, codim, + loop.from, loop.to, 0, GFC_ARRAY_UNKNOWN, false); parm = gfc_create_var (parmtype, "parm"); } @@ -6036,7 +6047,6 @@ gfc_conv_expr_descriptor (gfc_se * se, gfc_expr * expr, gfc_ss * ss) base = NULL_TREE; ndim = info->ref ? info->ref->u.ar.dimen : info->dimen; - codim = info->codimen; for (n = 0; n < ndim; n++) { stride = gfc_conv_array_stride (desc, n); @@ -6140,22 +6150,13 @@ gfc_conv_expr_descriptor (gfc_se * se, gfc_expr * expr, gfc_ss * ss) for (n = ndim; n < ndim + codim; n++) { - /* look for the corresponding scalarizer dimension: dim. */ - for (dim = 0; dim < ndim + codim; dim++) - if (info->dim[dim] == n) - break; - - /* loop exited early: the DIM being looked for has been found. */ - gcc_assert (dim < ndim + codim); - - from = loop.from[dim]; - to = loop.to[dim]; + from = loop.from[n]; + to = loop.to[n]; gfc_conv_descriptor_lbound_set (&loop.pre, parm, - gfc_rank_cst[dim], from); + gfc_rank_cst[n], from); if (n < ndim + codim - 1) gfc_conv_descriptor_ubound_set (&loop.pre, parm, - gfc_rank_cst[dim], to); - dim++; + gfc_rank_cst[n], to); } if (se->data_not_needed) @@ -7622,12 +7623,6 @@ gfc_walk_variable_expr (gfc_ss * ss, gfc_expr * expr) ar = &ref->u.ar; - if (ar->as->rank == 0 && ref->next != NULL) - { - /* Scalar coarray. */ - continue; - } - switch (ar->type) { case AR_ELEMENT: @@ -7642,7 +7637,6 @@ gfc_walk_variable_expr (gfc_ss * ss, gfc_expr * expr) /* Make sure array is the same as array(:,:), this way we don't need to special case all the time. */ ar->dimen = ar->as->rank; - ar->codimen = 0; for (n = 0; n < ar->dimen; n++) { ar->dimen_type[n] = DIMEN_RANGE; @@ -7651,14 +7645,6 @@ gfc_walk_variable_expr (gfc_ss * ss, gfc_expr * expr) gcc_assert (ar->end[n] == NULL); gcc_assert (ar->stride[n] == NULL); } - for (n = ar->dimen; n < ar->dimen + ar->as->corank; n++) - { - newss->data.info.dim[n] = n; - ar->dimen_type[n] = DIMEN_RANGE; - - gcc_assert (ar->start[n] == NULL); - gcc_assert (ar->end[n] == NULL); - } ss = newss; break; @@ -7667,14 +7653,12 @@ gfc_walk_variable_expr (gfc_ss * ss, gfc_expr * expr) newss->data.info.ref = ref; /* We add SS chains for all the subscripts in the section. */ - for (n = 0; n < ar->dimen + ar->codimen; n++) + for (n = 0; n < ar->dimen; n++) { gfc_ss *indexss; switch (ar->dimen_type[n]) { - case DIMEN_THIS_IMAGE: - continue; case DIMEN_ELEMENT: /* Add SS for elemental (scalar) subscripts. */ gcc_assert (ar->start[n]); @@ -7686,10 +7670,8 @@ gfc_walk_variable_expr (gfc_ss * ss, gfc_expr * expr) case DIMEN_RANGE: /* We don't add anything for sections, just remember this dimension for later. */ - newss->data.info.dim[newss->data.info.dimen - + newss->data.info.codimen] = n; - if (n < ar->dimen) - newss->data.info.dimen++; + newss->data.info.dim[newss->data.info.dimen] = n; + newss->data.info.dimen++; break; case DIMEN_VECTOR: @@ -7699,10 +7681,8 @@ gfc_walk_variable_expr (gfc_ss * ss, gfc_expr * expr) 1, GFC_SS_VECTOR); indexss->loop_chain = gfc_ss_terminator; newss->data.info.subscript[n] = indexss; - newss->data.info.dim[newss->data.info.dimen - + newss->data.info.codimen] = n; - if (n < ar->dimen) - newss->data.info.dimen++; + newss->data.info.dim[newss->data.info.dimen] = n; + newss->data.info.dimen++; break; default: diff --git a/gcc/fortran/trans-common.c b/gcc/fortran/trans-common.c index 21237c8d8ec..61ce44ba37a 100644 --- a/gcc/fortran/trans-common.c +++ b/gcc/fortran/trans-common.c @@ -1067,14 +1067,12 @@ translate_common (gfc_common_head *common, gfc_symbol *var_list) HOST_WIDE_INT offset; HOST_WIDE_INT current_offset; unsigned HOST_WIDE_INT align; - unsigned HOST_WIDE_INT max_align; bool saw_equiv; common_segment = NULL; offset = 0; current_offset = 0; align = 1; - max_align = 1; saw_equiv = false; /* Add symbols to the segment. */ @@ -1117,7 +1115,7 @@ translate_common (gfc_common_head *common, gfc_symbol *var_list) if (gfc_option.flag_align_commons) offset = align_segment (&align); - if (offset & (max_align - 1)) + if (offset) { /* The required offset conflicts with previous alignment requirements. Insert padding immediately before this @@ -1140,8 +1138,6 @@ translate_common (gfc_common_head *common, gfc_symbol *var_list) /* Apply the offset to the new segments. */ apply_segment_offset (current_segment, offset); current_offset += offset; - if (max_align < align) - max_align = align; /* Add the new segments to the common block. */ common_segment = add_segments (common_segment, current_segment); @@ -1161,11 +1157,11 @@ translate_common (gfc_common_head *common, gfc_symbol *var_list) if (common_segment->offset != 0 && gfc_option.warn_align_commons) { if (strcmp (common->name, BLANK_COMMON_NAME)) - gfc_warning ("COMMON '%s' at %L requires %d bytes of padding at start; " + gfc_warning ("COMMON '%s' at %L requires %d bytes of padding; " "reorder elements or use -fno-align-commons", common->name, &common->where, (int)common_segment->offset); else - gfc_warning ("COMMON at %L requires %d bytes of padding at start; " + gfc_warning ("COMMON at %L requires %d bytes of padding; " "reorder elements or use -fno-align-commons", &common->where, (int)common_segment->offset); } diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c index 44363c298ae..4526aaabb3a 100644 --- a/gcc/fortran/trans-decl.c +++ b/gcc/fortran/trans-decl.c @@ -1179,7 +1179,10 @@ gfc_get_symbol_decl (gfc_symbol * sym) { gfc_component *c = CLASS_DATA (sym); if (!c->ts.u.derived->backend_decl) - gfc_find_derived_vtab (c->ts.u.derived); + { + gfc_find_derived_vtab (c->ts.u.derived); + gfc_get_derived_type (sym->ts.u.derived); + } } /* All deferred character length procedures need to retain the backend diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c index de5a809c81a..c47e678dfa7 100644 --- a/gcc/fortran/trans-intrinsic.c +++ b/gcc/fortran/trans-intrinsic.c @@ -924,18 +924,32 @@ gfc_conv_intrinsic_exponent (gfc_se *se, gfc_expr *expr) /* Convert the last ref of a scalar coarray from an AR_ELEMENT to an AR_FULL, suitable for the scalarizer. */ -static void -convert_element_to_coarray_ref (gfc_expr *expr) +static gfc_ss * +walk_coarray (gfc_expr *e) { - gfc_ref *ref; + gfc_ss *ss; - for (ref = expr->ref; ref; ref = ref->next) - if (ref->type == REF_ARRAY && ref->next == NULL - && ref->u.ar.codimen) - { - ref->u.ar.type = AR_FULL; - break; - } + gcc_assert (gfc_get_corank (e) > 0); + + ss = gfc_walk_expr (e); + + /* Fix scalar coarray. */ + if (ss == gfc_ss_terminator) + { + gfc_ref *ref; + + ss = gfc_get_array_ss (gfc_ss_terminator, e, 0, GFC_SS_SECTION); + + ref = e->ref; + while (ref->next) + ref = ref->next; + + gcc_assert (ref->type == REF_ARRAY && ref->u.ar.codimen > 0); + ref->u.ar.type = AR_FULL; + ss->data.info.ref = ref; + } + + return ss; } @@ -969,11 +983,9 @@ trans_this_image (gfc_se * se, gfc_expr *expr) /* Obtain the descriptor of the COARRAY. */ gfc_init_se (&argse, NULL); - if (expr->value.function.actual->expr->rank == 0) - convert_element_to_coarray_ref (expr->value.function.actual->expr); - ss = gfc_walk_expr (expr->value.function.actual->expr); + ss = walk_coarray (expr->value.function.actual->expr); gcc_assert (ss != gfc_ss_terminator); - ss->data.info.codimen = corank; + argse.want_coarray = 1; gfc_conv_expr_descriptor (&argse, expr->value.function.actual->expr, ss); gfc_add_block_to_block (&se->pre, &argse.pre); gfc_add_block_to_block (&se->post, &argse.post); @@ -1156,11 +1168,9 @@ trans_image_index (gfc_se * se, gfc_expr *expr) /* Obtain the descriptor of the COARRAY. */ gfc_init_se (&argse, NULL); - if (expr->value.function.actual->expr->rank == 0) - convert_element_to_coarray_ref (expr->value.function.actual->expr); - ss = gfc_walk_expr (expr->value.function.actual->expr); + ss = walk_coarray (expr->value.function.actual->expr); gcc_assert (ss != gfc_ss_terminator); - ss->data.info.codimen = corank; + argse.want_coarray = 1; gfc_conv_expr_descriptor (&argse, expr->value.function.actual->expr, ss); gfc_add_block_to_block (&se->pre, &argse.pre); gfc_add_block_to_block (&se->post, &argse.post); @@ -1482,12 +1492,10 @@ conv_intrinsic_cobound (gfc_se * se, gfc_expr * expr) gcc_assert (arg->expr->expr_type == EXPR_VARIABLE); corank = gfc_get_corank (arg->expr); - if (expr->value.function.actual->expr->rank == 0) - convert_element_to_coarray_ref (expr->value.function.actual->expr); - ss = gfc_walk_expr (arg->expr); + ss = walk_coarray (arg->expr); gcc_assert (ss != gfc_ss_terminator); - ss->data.info.codimen = corank; gfc_init_se (&argse, NULL); + argse.want_coarray = 1; gfc_conv_expr_descriptor (&argse, arg->expr, ss); gfc_add_block_to_block (&se->pre, &argse.pre); diff --git a/gcc/fortran/trans-types.c b/gcc/fortran/trans-types.c index aa8e43bd8b8..4c5990e7ae1 100644 --- a/gcc/fortran/trans-types.c +++ b/gcc/fortran/trans-types.c @@ -298,8 +298,8 @@ get_int_kind_from_minimal_width (int size) /* Generate the CInteropKind_t objects for the C interoperable kinds. */ -static -void init_c_interop_kinds (void) +void +gfc_init_c_interop_kinds (void) { int i; @@ -316,11 +316,11 @@ void init_c_interop_kinds (void) strncpy (c_interop_kinds_table[a].name, b, strlen(b) + 1); \ c_interop_kinds_table[a].f90_type = BT_INTEGER; \ c_interop_kinds_table[a].value = c; -#define NAMED_REALCST(a,b,c) \ +#define NAMED_REALCST(a,b,c,d) \ strncpy (c_interop_kinds_table[a].name, b, strlen(b) + 1); \ c_interop_kinds_table[a].f90_type = BT_REAL; \ c_interop_kinds_table[a].value = c; -#define NAMED_CMPXCST(a,b,c) \ +#define NAMED_CMPXCST(a,b,c,d) \ strncpy (c_interop_kinds_table[a].name, b, strlen(b) + 1); \ c_interop_kinds_table[a].f90_type = BT_COMPLEX; \ c_interop_kinds_table[a].value = c; @@ -584,11 +584,9 @@ gfc_init_kinds (void) /* Choose atomic kinds to match C's int. */ gfc_atomic_int_kind = gfc_c_int_kind; gfc_atomic_logical_kind = gfc_c_int_kind; - - /* initialize the C interoperable kinds */ - init_c_interop_kinds(); } + /* Make sure that a valid kind is present. Returns an index into the associated kinds array, -1 if the kind is not present. */ diff --git a/gcc/fortran/trans-types.h b/gcc/fortran/trans-types.h index 57afd8caef9..2ab94b3f184 100644 --- a/gcc/fortran/trans-types.h +++ b/gcc/fortran/trans-types.h @@ -58,6 +58,7 @@ void gfc_convert_function_code (gfc_namespace *); /* trans-types.c */ void gfc_init_kinds (void); void gfc_init_types (void); +void gfc_init_c_interop_kinds (void); tree gfc_get_int_type (int); tree gfc_get_real_type (int); diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h index 0c249a6736a..535c207fcd4 100644 --- a/gcc/fortran/trans.h +++ b/gcc/fortran/trans.h @@ -86,6 +86,8 @@ typedef struct gfc_se args alias. */ unsigned force_tmp:1; + unsigned want_coarray:1; + /* Scalarization parameters. */ struct gfc_se *parent; struct gfc_ss *ss; @@ -116,7 +118,7 @@ gfc_coarray_type; typedef struct gfc_ss_info { - int dimen, codimen; + int dimen; /* The ref that holds information on this section. */ gfc_ref *ref; /* The descriptor of this array. */ @@ -210,7 +212,7 @@ typedef struct gfc_ss { /* The rank of the temporary. May be less than the rank of the assigned expression. */ - int dimen, codimen; + int dimen; tree type; } temp; @@ -243,7 +245,7 @@ typedef struct gfc_loopinfo stmtblock_t pre; stmtblock_t post; - int dimen, codimen; + int dimen; /* All the SS involved with this loop. */ gfc_ss *ss; diff --git a/gcc/function.c b/gcc/function.c index 6484916cef0..ae9b535550d 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -3635,8 +3635,10 @@ gimplify_parameters (void) DECL_IGNORED_P (addr) = 0; local = build_fold_indirect_ref (addr); - t = built_in_decls[BUILT_IN_ALLOCA]; - t = build_call_expr (t, 1, DECL_SIZE_UNIT (parm)); + t = built_in_decls[BUILT_IN_ALLOCA_WITH_ALIGN]; + t = build_call_expr (t, 1, DECL_SIZE_UNIT (parm), + size_int (DECL_ALIGN (parm))); + /* The call has been built for a variable-sized object. */ CALL_ALLOCA_FOR_VAR_P (t) = 1; t = fold_convert (ptr_type, t); @@ -5303,25 +5305,15 @@ record_hard_reg_uses (rtx *px, void *data) for_each_rtx (px, record_hard_reg_uses_1, data); } -/* A subroutine of requires_stack_frame_p, called via for_each_rtx. - Return 1 if we found an rtx that forces a prologue, zero otherwise. */ -static int -frame_required_for_rtx (rtx *loc, void *data ATTRIBUTE_UNUSED) -{ - rtx x = *loc; - if (x == stack_pointer_rtx || x == hard_frame_pointer_rtx - || x == arg_pointer_rtx || x == pic_offset_table_rtx) - return 1; - return 0; -} - /* Return true if INSN requires the stack frame to be set up. PROLOGUE_USED contains the hard registers used in the function - prologue. */ + prologue. SET_UP_BY_PROLOGUE is the set of registers we expect the + prologue to set up for the function. */ static bool -requires_stack_frame_p (rtx insn, HARD_REG_SET prologue_used) +requires_stack_frame_p (rtx insn, HARD_REG_SET prologue_used, + HARD_REG_SET set_up_by_prologue) { - df_ref *def_rec; + df_ref *df_rec; HARD_REG_SET hardregs; unsigned regno; @@ -5329,13 +5321,11 @@ requires_stack_frame_p (rtx insn, HARD_REG_SET prologue_used) return false; if (CALL_P (insn)) return !SIBLING_CALL_P (insn); - if (for_each_rtx (&PATTERN (insn), frame_required_for_rtx, NULL)) - return true; CLEAR_HARD_REG_SET (hardregs); - for (def_rec = DF_INSN_DEFS (insn); *def_rec; def_rec++) + for (df_rec = DF_INSN_DEFS (insn); *df_rec; df_rec++) { - rtx dreg = DF_REF_REG (*def_rec); + rtx dreg = DF_REF_REG (*df_rec); if (!REG_P (dreg)) continue; @@ -5350,6 +5340,20 @@ requires_stack_frame_p (rtx insn, HARD_REG_SET prologue_used) if (TEST_HARD_REG_BIT (hardregs, regno) && df_regs_ever_live_p (regno)) return true; + + for (df_rec = DF_INSN_USES (insn); *df_rec; df_rec++) + { + rtx reg = DF_REF_REG (*df_rec); + + if (!REG_P (reg)) + continue; + + add_to_hard_reg_set (&hardregs, GET_MODE (reg), + REGNO (reg)); + } + if (hard_reg_set_intersect_p (hardregs, set_up_by_prologue)) + return true; + return false; } #endif @@ -5453,9 +5457,9 @@ thread_prologue_and_epilogue_insns (void) { bool inserted; basic_block last_bb; - bool last_bb_active; + bool last_bb_active ATTRIBUTE_UNUSED; #ifdef HAVE_simple_return - bool unconverted_simple_returns = false; + VEC (rtx, heap) *unconverted_simple_returns = NULL; basic_block simple_return_block_hot = NULL; basic_block simple_return_block_cold = NULL; bool nonempty_prologue; @@ -5575,6 +5579,7 @@ thread_prologue_and_epilogue_insns (void) && nonempty_prologue && !crtl->calls_eh_return) { HARD_REG_SET prologue_clobbered, prologue_used, live_on_edge; + HARD_REG_SET set_up_by_prologue; rtx p_insn; VEC(basic_block, heap) *vec; @@ -5602,10 +5607,6 @@ thread_prologue_and_epilogue_insns (void) note_stores (PATTERN (p_insn), record_hard_reg_sets, &prologue_clobbered); } - for (p_insn = split_prologue_seq; p_insn; p_insn = NEXT_INSN (p_insn)) - if (NONDEBUG_INSN_P (p_insn)) - note_stores (PATTERN (p_insn), record_hard_reg_sets, - &prologue_clobbered); bitmap_initialize (&bb_antic_flags, &bitmap_default_obstack); bitmap_initialize (&bb_on_list, &bitmap_default_obstack); @@ -5614,6 +5615,16 @@ thread_prologue_and_epilogue_insns (void) vec = VEC_alloc (basic_block, heap, n_basic_blocks); + CLEAR_HARD_REG_SET (set_up_by_prologue); + add_to_hard_reg_set (&set_up_by_prologue, Pmode, STACK_POINTER_REGNUM); + add_to_hard_reg_set (&set_up_by_prologue, Pmode, ARG_POINTER_REGNUM); + if (frame_pointer_needed) + add_to_hard_reg_set (&set_up_by_prologue, Pmode, + HARD_FRAME_POINTER_REGNUM); + if (pic_offset_table_rtx) + add_to_hard_reg_set (&set_up_by_prologue, Pmode, + PIC_OFFSET_TABLE_REGNUM); + FOR_EACH_BB (bb) { rtx insn; @@ -5632,7 +5643,8 @@ thread_prologue_and_epilogue_insns (void) } else FOR_BB_INSNS (bb, insn) - if (requires_stack_frame_p (insn, prologue_used)) + if (requires_stack_frame_p (insn, prologue_used, + set_up_by_prologue)) { bitmap_set_bit (&bb_flags, bb->index); VEC_quick_push (basic_block, vec, bb); @@ -5758,7 +5770,7 @@ thread_prologue_and_epilogue_insns (void) if (split_prologue_seq != NULL_RTX) { - insert_insn_on_edge (split_prologue_seq, entry_edge); + insert_insn_on_edge (split_prologue_seq, orig_entry_edge); inserted = true; } if (prologue_seq != NULL_RTX) @@ -5876,7 +5888,8 @@ thread_prologue_and_epilogue_insns (void) { #ifdef HAVE_simple_return if (simple_p) - unconverted_simple_returns = true; + VEC_safe_push (rtx, heap, + unconverted_simple_returns, jump); #endif continue; } @@ -5894,7 +5907,8 @@ thread_prologue_and_epilogue_insns (void) { #ifdef HAVE_simple_return if (simple_p) - unconverted_simple_returns = true; + VEC_safe_push (rtx, heap, + unconverted_simple_returns, jump); #endif continue; } @@ -6024,6 +6038,7 @@ epilogue_done: blocks = sbitmap_alloc (last_basic_block); sbitmap_zero (blocks); SET_BIT (blocks, entry_edge->dest->index); + SET_BIT (blocks, orig_entry_edge->dest->index); find_many_sub_basic_blocks (blocks); sbitmap_free (blocks); @@ -6042,10 +6057,11 @@ epilogue_done: convert to conditional simple_returns, but couldn't for some reason, create a block to hold a simple_return insn and redirect those remaining edges. */ - if (unconverted_simple_returns) + if (!VEC_empty (rtx, unconverted_simple_returns)) { - edge_iterator ei2; basic_block exit_pred = EXIT_BLOCK_PTR->prev_bb; + rtx jump; + int i; gcc_assert (entry_edge != orig_entry_edge); @@ -6062,19 +6078,13 @@ epilogue_done: simple_return_block_cold = e->dest; } - restart_scan: - for (ei2 = ei_start (last_bb->preds); (e = ei_safe_edge (ei2)); ) + FOR_EACH_VEC_ELT (rtx, unconverted_simple_returns, i, jump) { - basic_block bb = e->src; + basic_block src_bb = BLOCK_FOR_INSN (jump); + edge e = find_edge (src_bb, last_bb); basic_block *pdest_bb; - if (bb == ENTRY_BLOCK_PTR - || bitmap_bit_p (&bb_flags, bb->index)) - { - ei_next (&ei2); - continue; - } - if (BB_PARTITION (e->src) == BB_HOT_PARTITION) + if (BB_PARTITION (src_bb) == BB_HOT_PARTITION) pdest_bb = &simple_return_block_hot; else pdest_bb = &simple_return_block_cold; @@ -6094,8 +6104,8 @@ epilogue_done: make_edge (bb, EXIT_BLOCK_PTR, 0); } redirect_edge_and_branch_force (e, *pdest_bb); - goto restart_scan; } + VEC_free (rtx, heap, unconverted_simple_returns); } #endif diff --git a/gcc/genopinit.c b/gcc/genopinit.c index 4672075cd31..4eefa036cc7 100644 --- a/gcc/genopinit.c +++ b/gcc/genopinit.c @@ -253,7 +253,7 @@ static const char * const optabs[] = "set_optab_handler (vec_shl_optab, $A, CODE_FOR_$(vec_shl_$a$))", "set_optab_handler (vec_shr_optab, $A, CODE_FOR_$(vec_shr_$a$))", "set_optab_handler (vec_realign_load_optab, $A, CODE_FOR_$(vec_realign_load_$a$))", - "set_direct_optab_handler (vshuffle_optab, $A, CODE_FOR_$(vshuffle$a$))", + "set_direct_optab_handler (vec_perm_optab, $A, CODE_FOR_$(vec_perm$a$))", "set_convert_optab_handler (vcond_optab, $A, $B, CODE_FOR_$(vcond$a$b$))", "set_convert_optab_handler (vcondu_optab, $A, $B, CODE_FOR_$(vcondu$a$b$))", "set_optab_handler (ssum_widen_optab, $A, CODE_FOR_$(widen_ssum$I$a3$))", diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index fcfbcc8f5b3..b4993fdef92 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -828,6 +828,11 @@ gimple_fold_builtin (gimple stmt) if (DECL_BUILT_IN_CLASS (callee) == BUILT_IN_MD) return NULL_TREE; + /* Give up for always_inline inline builtins until they are + inlined. */ + if (avoid_folding_inline_builtin (callee)) + return NULL_TREE; + /* If the builtin could not be folded, and it has no argument list, we're done. */ nargs = gimple_call_num_args (stmt); diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c index 2dbdebe339e..577d28bb1f7 100644 --- a/gcc/gimple-pretty-print.c +++ b/gcc/gimple-pretty-print.c @@ -418,8 +418,8 @@ dump_ternary_rhs (pretty_printer *buffer, gimple gs, int spc, int flags) pp_string (buffer, ">"); break; - case VEC_SHUFFLE_EXPR: - pp_string (buffer, "VEC_SHUFFLE_EXPR <"); + case VEC_PERM_EXPR: + pp_string (buffer, "VEC_PERM_EXPR <"); dump_generic_node (buffer, gimple_assign_rhs1 (gs), spc, flags, false); pp_string (buffer, ", "); dump_generic_node (buffer, gimple_assign_rhs2 (gs), spc, flags, false); diff --git a/gcc/gimple.c b/gcc/gimple.c index e4dfd467d75..19f02dc9cd1 100644 --- a/gcc/gimple.c +++ b/gcc/gimple.c @@ -374,7 +374,8 @@ gimple_build_call_from_tree (tree t) gimple_call_set_return_slot_opt (call, CALL_EXPR_RETURN_SLOT_OPT (t)); if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL - && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_ALLOCA) + && (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_ALLOCA + || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_ALLOCA_WITH_ALIGN)) gimple_call_set_alloca_for_var (call, CALL_ALLOCA_FOR_VAR_P (t)); else gimple_call_set_from_thunk (call, CALL_FROM_THUNK_P (t)); @@ -2638,7 +2639,7 @@ get_gimple_rhs_num_ops (enum tree_code code) || (SYM) == DOT_PROD_EXPR \ || (SYM) == REALIGN_LOAD_EXPR \ || (SYM) == VEC_COND_EXPR \ - || (SYM) == VEC_SHUFFLE_EXPR \ + || (SYM) == VEC_PERM_EXPR \ || (SYM) == FMA_EXPR) ? GIMPLE_TERNARY_RHS \ : ((SYM) == CONSTRUCTOR \ || (SYM) == OBJ_TYPE_REF \ diff --git a/gcc/gimplify.c b/gcc/gimplify.c index 4c15f3a7c45..9713218fa10 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -1329,8 +1329,9 @@ gimplify_vla_decl (tree decl, gimple_seq *seq_p) SET_DECL_VALUE_EXPR (decl, t); DECL_HAS_VALUE_EXPR_P (decl) = 1; - t = built_in_decls[BUILT_IN_ALLOCA]; - t = build_call_expr (t, 1, DECL_SIZE_UNIT (decl)); + t = built_in_decls[BUILT_IN_ALLOCA_WITH_ALIGN]; + t = build_call_expr (t, 2, DECL_SIZE_UNIT (decl), + size_int (DECL_ALIGN (decl))); /* The call has been built for a variable-sized object. */ CALL_ALLOCA_FOR_VAR_P (t) = 1; t = fold_convert (ptr_type, t); @@ -7286,7 +7287,7 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, } case FMA_EXPR: - case VEC_SHUFFLE_EXPR: + case VEC_PERM_EXPR: /* Classified as tcc_expression. */ goto expr_3; diff --git a/gcc/hooks.c b/gcc/hooks.c index 1ba44f9c7bb..ae59c333d61 100644 --- a/gcc/hooks.c +++ b/gcc/hooks.c @@ -132,6 +132,14 @@ hook_void_FILEptr_constcharptr (FILE *a ATTRIBUTE_UNUSED, const char *b ATTRIBUT { } +/* Generic hook that takes (FILE *, rtx) and returns false. */ +bool +hook_bool_FILEptr_rtx_false (FILE *a ATTRIBUTE_UNUSED, + rtx b ATTRIBUTE_UNUSED) +{ + return false; +} + /* Used for the TARGET_ASM_CAN_OUTPUT_MI_THUNK hook. */ bool hook_bool_const_tree_hwi_hwi_const_tree_false (const_tree a ATTRIBUTE_UNUSED, diff --git a/gcc/hooks.h b/gcc/hooks.h index 54ace243f76..2e10d1fd682 100644 --- a/gcc/hooks.h +++ b/gcc/hooks.h @@ -63,6 +63,7 @@ extern void hook_void_void (void); extern void hook_void_constcharptr (const char *); extern void hook_void_rtx_int (rtx, int); extern void hook_void_FILEptr_constcharptr (FILE *, const char *); +extern bool hook_bool_FILEptr_rtx_false (FILE *, rtx); extern void hook_void_tree (tree); extern void hook_void_tree_treeptr (tree, tree *); extern void hook_void_int_int (int, int); diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c index 36212cda67b..82e24cf5a01 100644 --- a/gcc/ipa-pure-const.c +++ b/gcc/ipa-pure-const.c @@ -437,6 +437,7 @@ special_builtin_state (enum pure_const_state_e *state, bool *looping, case BUILT_IN_RETURN: case BUILT_IN_UNREACHABLE: case BUILT_IN_ALLOCA: + case BUILT_IN_ALLOCA_WITH_ALIGN: case BUILT_IN_STACK_SAVE: case BUILT_IN_STACK_RESTORE: case BUILT_IN_EH_POINTER: diff --git a/gcc/melt-runtime.h b/gcc/melt-runtime.h index 98c1625f4f9..5b13da787aa 100644 --- a/gcc/melt-runtime.h +++ b/gcc/melt-runtime.h @@ -328,8 +328,8 @@ void melt_dbgbacktrace (int depth); /* A pretty printing FILE, possibly in memory, or sort-of! */ extern FILE* meltppfile; -char* meltppbuffer; -size_t meltppbufsiz; +extern char* meltppbuffer; +extern size_t meltppbufsiz; /* Open a new pretty printing file into meltppfile, return the old one. */ FILE* melt_open_ppfile (void); diff --git a/gcc/optabs.c b/gcc/optabs.c index 3a52fb0c07c..0ba13335186 100644 --- a/gcc/optabs.c +++ b/gcc/optabs.c @@ -6620,10 +6620,10 @@ vector_compare_rtx (tree cond, bool unsignedp, enum insn_code icode) return gen_rtx_fmt_ee (rcode, VOIDmode, ops[0].value, ops[1].value); } -/* Return true if VEC_SHUFFLE_EXPR can be expanded using SIMD extensions +/* Return true if VEC_PERM_EXPR can be expanded using SIMD extensions of the CPU. */ bool -expand_vec_shuffle_expr_p (enum machine_mode mode, tree v0, tree v1, tree mask) +expand_vec_perm_expr_p (enum machine_mode mode, tree v0, tree v1, tree mask) { int v0_mode_s = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (TREE_TYPE (v0)))); int mask_mode_s = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (TREE_TYPE (mask)))); @@ -6639,20 +6639,19 @@ expand_vec_shuffle_expr_p (enum machine_mode mode, tree v0, tree v1, tree mask) != TYPE_VECTOR_SUBPARTS (TREE_TYPE (mask))) return false; - return direct_optab_handler (vshuffle_optab, mode) != CODE_FOR_nothing; + return direct_optab_handler (vec_perm_optab, mode) != CODE_FOR_nothing; } /* Generate instructions for VEC_COND_EXPR given its type and three operands. */ rtx -expand_vec_shuffle_expr (tree type, tree v0, tree v1, tree mask, rtx target) +expand_vec_perm_expr (tree type, tree v0, tree v1, tree mask, rtx target) { struct expand_operand ops[4]; enum insn_code icode; enum machine_mode mode = TYPE_MODE (type); - rtx rtx_v0, rtx_mask; - gcc_assert (expand_vec_shuffle_expr_p (mode, v0, v1, mask)); + gcc_checking_assert (expand_vec_perm_expr_p (mode, v0, v1, mask)); if (TREE_CODE (mask) == VECTOR_CST) { @@ -6660,7 +6659,7 @@ expand_vec_shuffle_expr (tree type, tree v0, tree v1, tree mask, rtx target) tree fn = targetm.vectorize.builtin_vec_perm (TREE_TYPE (v0), &m_type); if (!fn) - goto vshuffle; + goto vec_perm; if (m_type != TREE_TYPE (TREE_TYPE (mask))) { @@ -6675,24 +6674,23 @@ expand_vec_shuffle_expr (tree type, tree v0, tree v1, tree mask, rtx target) return expand_expr_real_1 (call, target, VOIDmode, EXPAND_NORMAL, NULL); } -vshuffle: - icode = direct_optab_handler (vshuffle_optab, mode); + vec_perm: + icode = direct_optab_handler (vec_perm_optab, mode); if (icode == CODE_FOR_nothing) return 0; - rtx_mask = expand_normal (mask); - create_output_operand (&ops[0], target, mode); - create_input_operand (&ops[3], rtx_mask, mode); + create_input_operand (&ops[3], expand_normal (mask), + TYPE_MODE (TREE_TYPE (mask))); if (operand_equal_p (v0, v1, 0)) { - rtx_v0 = expand_normal (v0); - if (!insn_operand_matches(icode, 1, rtx_v0)) + rtx rtx_v0 = expand_normal (v0); + if (!insn_operand_matches (icode, 1, rtx_v0)) rtx_v0 = force_reg (mode, rtx_v0); - gcc_checking_assert(insn_operand_matches(icode, 2, rtx_v0)); + gcc_checking_assert (insn_operand_matches (icode, 2, rtx_v0)); create_fixed_operand (&ops[1], rtx_v0); create_fixed_operand (&ops[2], rtx_v0); diff --git a/gcc/optabs.h b/gcc/optabs.h index 5d5593bb095..4b46bda3a3c 100644 --- a/gcc/optabs.h +++ b/gcc/optabs.h @@ -377,6 +377,9 @@ enum optab_index OTI_vec_pack_sfix_trunc, OTI_vec_pack_ufix_trunc, + /* Vector shuffling. */ + OTI_vec_perm, + /* Perform a raise to the power of integer. */ OTI_powi, @@ -557,6 +560,7 @@ enum optab_index #define vec_pack_usat_optab (&optab_table[OTI_vec_pack_usat]) #define vec_pack_sfix_trunc_optab (&optab_table[OTI_vec_pack_sfix_trunc]) #define vec_pack_ufix_trunc_optab (&optab_table[OTI_vec_pack_ufix_trunc]) +#define vec_perm_optab (&direct_optab_table[(int) OTI_vec_perm]) #define powi_optab (&optab_table[OTI_powi]) @@ -617,7 +621,6 @@ enum convert_optab_index #define vec_store_lanes_optab (&convert_optab_table[COI_vec_store_lanes]) #define vcond_optab (&convert_optab_table[(int) COI_vcond]) #define vcondu_optab (&convert_optab_table[(int) COI_vcondu]) -#define vshuffle_optab (&direct_optab_table[(int) DOI_vshuffle]) /* Contains the optab used for each rtx code. */ extern optab code_to_optab[NUM_RTX_CODE + 1]; @@ -639,9 +642,6 @@ enum direct_optab_index DOI_reload_in, DOI_reload_out, - /* Vector shuffling. */ - DOI_vshuffle, - /* Block move operation. */ DOI_movmem, @@ -888,11 +888,11 @@ extern rtx expand_vec_cond_expr (tree, tree, tree, tree, rtx); /* Generate code for VEC_LSHIFT_EXPR and VEC_RSHIFT_EXPR. */ extern rtx expand_vec_shift_expr (sepops, rtx); -/* Return tree if target supports vector operations for VEC_SHUFFLE_EXPR. */ -bool expand_vec_shuffle_expr_p (enum machine_mode, tree, tree, tree); +/* Return tree if target supports vector operations for VEC_PERM_EXPR. */ +bool expand_vec_perm_expr_p (enum machine_mode, tree, tree, tree); -/* Generate code for VEC_SHUFFLE_EXPR. */ -extern rtx expand_vec_shuffle_expr (tree, tree, tree, tree, rtx); +/* Generate code for VEC_PERM_EXPR. */ +extern rtx expand_vec_perm_expr (tree, tree, tree, tree, rtx); /* Return the insn used to implement mode MODE of OP, or CODE_FOR_nothing if the target does not have such an insn. */ diff --git a/gcc/system.h b/gcc/system.h index 340a560df2a..7c006faaafe 100644 --- a/gcc/system.h +++ b/gcc/system.h @@ -797,7 +797,8 @@ extern void fancy_abort (const char *, int, const char *) ATTRIBUTE_NORETURN; LABEL_ALIGN_MAX_SKIP LOOP_ALIGN_MAX_SKIP \ LABEL_ALIGN_AFTER_BARRIER_MAX_SKIP JUMP_ALIGN_MAX_SKIP \ CAN_DEBUG_WITHOUT_FP UNLIKELY_EXECUTED_TEXT_SECTION_NAME \ - HOT_TEXT_SECTION_NAME LEGITIMATE_CONSTANT_P ALWAYS_STRIP_DOTDOT + HOT_TEXT_SECTION_NAME LEGITIMATE_CONSTANT_P ALWAYS_STRIP_DOTDOT \ + OUTPUT_ADDR_CONST_EXTRA /* Target macros only used for code built for the target, that have moved to libgcc-tm.h or have never been present elsewhere. */ diff --git a/gcc/target.def b/gcc/target.def index 48a8e6d4a13..c3bec0e0391 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -456,7 +456,7 @@ DEFHOOK (output_addr_const_extra, "", bool, (FILE *file, rtx x), - default_asm_output_addr_const_extra) + hook_bool_FILEptr_rtx_false) /* ??? The TARGET_PRINT_OPERAND* hooks are part of the asm_out struct, even though that is not reflected in the macro name to override their diff --git a/gcc/targhooks.c b/gcc/targhooks.c index 8ad517fd5ce..81fd12f7b78 100644 --- a/gcc/targhooks.c +++ b/gcc/targhooks.c @@ -371,21 +371,6 @@ default_mangle_assembler_name (const char *name ATTRIBUTE_UNUSED) return get_identifier (stripped); } -/* The default implementation of TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA. */ - -bool -default_asm_output_addr_const_extra (FILE *file ATTRIBUTE_UNUSED, - rtx x ATTRIBUTE_UNUSED) -{ -#ifdef OUTPUT_ADDR_CONST_EXTRA - OUTPUT_ADDR_CONST_EXTRA (file, x, fail); - return true; - -fail: -#endif - return false; -} - /* True if MODE is valid for the target. By "valid", we mean able to be manipulated in non-trivial ways. In particular, this means all the arithmetic is supported. diff --git a/gcc/targhooks.h b/gcc/targhooks.h index 552407b21db..f19fb506bf5 100644 --- a/gcc/targhooks.h +++ b/gcc/targhooks.h @@ -67,8 +67,6 @@ extern void default_print_operand_address (FILE *, rtx); extern bool default_print_operand_punct_valid_p (unsigned char); extern tree default_mangle_assembler_name (const char *); -extern bool default_asm_output_addr_const_extra (FILE *, rtx); - extern bool default_scalar_mode_supported_p (enum machine_mode); extern bool targhook_words_big_endian (void); extern bool targhook_float_words_big_endian (void); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index cbd8f7147bf..d3be0344435 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,178 @@ +2011-10-09 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/38980 + * g++.dg/warn/format5.C: New. + +2011-10-09 Tobias Burnus <burnus@net-b.de> + + PR fortran/45044 + * gfortran.dg/common_14.f90: Compile with -Wno-align-commons. + * gfortran.dg/common_16.f90: New. + +2011-10-09 Tobias Burnus <burnus@net-b.de> + + * gfortran.dg/iso_c_binding_param_1.f90: New. + * gfortran.dg/iso_c_binding_param_2.f90: New. + * gfortran.dg/c_sizeof_2.f90: Update dg-error. + +2011-10-09 Ira Rosen <ira.rosen@linaro.org> + + PR tree-optimization/50635 + * gcc.dg/vect/pr50635.c: New test. + +2011-10-09 Janus Weil <janus@gcc.gnu.org> + + PR fortran/50659 + * gfortran.dg/proc_decl_27.f90: New. + +2011-10-08 Nicola Pero <nicola.pero@meta-innovation.com> + + PR libobjc/50428 + * objc/execute/initialize-1.m: New test. + +2011-10-08 Paul Thomas <pault@gcc.gnu.org> + + PR fortran/47844 + * gfortran.dg/pointer_function_result_1.f90 : New test. + +2011-10-07 David S. Miller <davem@davemloft.net> + + PR 50655 + * gcc.target/sparc/sparc.exp: Add vis3 target test. + * gcc.target/sparc/cmask.c: Use it. + * gcc.target/sparc/fhalve.c: Likewise. + * gcc.target/sparc/fnegop.c: Likewise. + * gcc.target/sparc/fpadds.c: Likewise. + * gcc.target/sparc/fshift.c: Likewise. + * gcc.target/sparc/fucmp.c: Likewise. + * gcc.target/sparc/lzd.c: Likewise. + * gcc.target/sparc/vis3misc.c: Likewise. + * gcc.target/sparc/xmul.c: Likewise. + +2011-10-07 Richard Henderson <rth@redhat.com> + + * gcc.target/i386/avx256-unaligned-load-2.c: Tweek vinsert pattern + match for avx2. + * gcc.target/i386/avx256-unaligned-store-2.c: Similarly. + +2011-10-07 Andrew Stubbs <ams@codesourcery.com> + + * gcc.dg/pr50193-1.c: New file. + * gcc.target/arm/shiftable.c: New file. + +2011-10-07 Janus Weil <janus@gcc.gnu.org> + + PR fortran/50625 + * gfortran.dg/class_46.f03: New. + +2011-10-06 Joern Rennecke <joern.rennecke@embecosm.com> + + * gcc.dg/pr47276.c (ASMNAME, ASMNAME2, STRING): Define. + (__EI___vsyslog_chk, __EI_syslog, __EI_vsyslog): Use ASMNAME. + (syslog, vsyslog, __vsyslog_chk): Likewise. + + * gcc.dg/lto/20081222_1.c (ASMNAME, ASMNAME2, STRING): Define. + (x, EXT_x): Use ASMNAME. + + * gcc.dg/torture/pr48044.c (ASMNAME, ASMNAME2, STRING): Define. + (a, c): Use ASMNAME. + +2011-10-07 Tom de Vries <tom@codesourcery.com> + + PR middle-end/50527 + * gcc.dg/pr50527.c: New test. + +2011-10-07 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/50650 + * gcc.c-torture/compile/pr50650.c: New test. + +2011-10-07 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> + + PR tree-optimization/50575 + * gcc.c-torture/execute/vector-compare-2.x: New file. + +2011-10-07 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> + + PR middle-end/50125 + * gcc.dg/uninit-B.c (baz): Remove xfail *-*-*. + * gcc.dg/uninit-pr19430.c (main): Remove xfail *-*-*. + (bar3): Likewise. + +2011-10-07 Richard Guenther <rguenther@suse.de> + + PR testsuite/50637 + * gcc.dg/vect/vect-align-2.c: Increase array size. + +2011-10-07 Uros Bizjak <ubizjak@gmail.com> + H.J. Lu <hongjiu.lu@intel.com> + + PR target/50603 + * gcc.target/i386/pr50603.c: New test. + +2011-10-06 Jason Merrill <jason@redhat.com> + + PR c++/39164 + * g++.dg/cpp0x/default31.C: New. + +2011-10-06 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/50596 + * lib/target-supports.exp (check_effective_target_vect_cond_mixed): + New. + * gcc.dg/vect/vect-cond-8.c: New test. + +2011-10-06 Richard Henderson <rth@redhat.com> + + * gcc.c-torture/execute/vect-shuffle-1.c: Remove. + * gcc.c-torture/execute/vect-shuffle-2.c: Remove. + * gcc.c-torture/execute/vect-shuffle-3.c: Remove. + * gcc.c-torture/execute/vect-shuffle-4.c: Remove. + * gcc.c-torture/execute/vect-shuffle-5.c: Remove. + * gcc.c-torture/execute/vect-shuffle-6.c: Remove. + * gcc.c-torture/execute/vect-shuffle-7.c: Remove. + * gcc.c-torture/execute/vect-shuffle-8.c: Remove. + * gcc.c-torture/execute/vshuf-16.inc: New file. + * gcc.c-torture/execute/vshuf-2.inc: New file. + * gcc.c-torture/execute/vshuf-4.inc: New file. + * gcc.c-torture/execute/vshuf-8.inc: New file. + * gcc.c-torture/execute/vshuf-main.inc: New file. + * gcc.c-torture/execute/vshuf-v16qi.c: New test. + * gcc.c-torture/execute/vshuf-v2df.c: New test. + * gcc.c-torture/execute/vshuf-v2di.c: New test. + * gcc.c-torture/execute/vshuf-v2sf.c: New test. + * gcc.c-torture/execute/vshuf-v2si.c: New test. + * gcc.c-torture/execute/vshuf-v4df.c: New test. + * gcc.c-torture/execute/vshuf-v4di.c: New test. + * gcc.c-torture/execute/vshuf-v4hi.c: New test. + * gcc.c-torture/execute/vshuf-v4sf.c: New test. + * gcc.c-torture/execute/vshuf-v4si.c: New test. + * gcc.c-torture/execute/vshuf-v8hi.c: New test. + * gcc.c-torture/execute/vshuf-v8qi.c: New test. + * gcc.c-torture/execute/vshuf-v8si.c: New test. + +2011-10-06 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/49279 + * gcc.dg/tree-ssa/restrict-4.c: XFAIL. + * gcc.c-torture/execute/pr49279.c: New test. + +2011-10-06 Bernd Schmidt <bernds@codesourcery.com> + + PR target/49049 + * gcc.c-torture/compile/pr49049.c: New test. + +2011-10-06 Ulrich Weigand <ulrich.weigand@linaro.org> + + PR target/50305 + * gcc.target/arm/pr50305.c: New test. + +2011-10-06 Richard Guenther <rguenther@suse.de> + + PR tree-optimization/38884 + * gcc.dg/tree-ssa/ssa-fre-34.c: New testcase. + * gcc.dg/tree-ssa/ssa-fre-35.c: Likewise. + 2011-10-05 David S. Miller <davem@davemloft.net> * gcc.target/sparc/lzd.c: New test. @@ -81,8 +256,7 @@ 2011-10-04 Artem Shinkarov <artyom.shinkaroff@gmail.com> - * gcc.c-torture/execute/vector-compare-1.c: Fix trailing white - spaces. + * gcc.c-torture/execute/vector-compare-1.c: Fix trailing white spaces. (main): Use __typeof to get result type of comparison. 2011-10-04 Ira Rosen <ira.rosen@linaro.org> @@ -235,8 +409,8 @@ PR testsuite/50485 * gcc.target/i386/sse4_1-blendps.c: Include <stdlib.h>. (TEST): Initialize src3 with random floats. - * gcc.target/i386/sse4_1-blendps-2.c (sse4_1_test): Remove field i from - union src3. Initialize src3 with random floats. + * gcc.target/i386/sse4_1-blendps-2.c (sse4_1_test): Remove field i + from union src3. Initialize src3 with random floats. 2011-09-27 Oleg Endo <oleg.endo@t-online.de> @@ -596,8 +770,7 @@ 2011-09-20 H.J. Lu <hongjiu.lu@intel.com> PR testsuite/50469 - * gfortran.dg/storage_size_2.f08: Replace "must be be" with - "must be". + * gfortran.dg/storage_size_2.f08: Replace "must be be" with "must be". 2011-09-20 Jason Merrill <jason@redhat.com> @@ -983,8 +1156,7 @@ gcc.dg/vect/vect-54.c, gcc.dg/vect/vect-46.c, gcc.dg/vect/vect-48.c, gcc.dg/vect/vect-96.c, gcc.dg/vect/vect-multitypes-3.c, gcc.dg/vect/vect-40.c: Likewise. - * gcc.dg/vect/vect-outer-5.c: Remove quad-vectors option as - redundant. + * gcc.dg/vect/vect-outer-5.c: Remove quad-vectors option as redundant. * gcc.dg/vect/vect-109.c, gcc.dg/vect/vect-peel-1.c, gcc.dg/vect/vect-peel-2.c, gcc.dg/vect/slp-25.c, gcc.dg/vect/vect-multitypes-1.c, gcc.dg/vect/slp-3.c, @@ -1041,8 +1213,8 @@ 2011-09-05 Georg-Johann Lay <avr@gjlay.de> - * gcc.dg/ipa/ipcp-3.c (mark_cell): Use mask 1 << 14 instead of 1 - << 18 to avoid warning on int=16 platforms.. + * gcc.dg/ipa/ipcp-3.c (mark_cell): Use mask 1 << 14 instead of 1 << 18 + to avoid warning on int=16 platforms.. 2011-09-05 Jakub Jelinek <jakub@redhat.com> diff --git a/gcc/testsuite/g++.dg/cpp0x/defaulted31.C b/gcc/testsuite/g++.dg/cpp0x/defaulted31.C new file mode 100644 index 00000000000..de6a29854a5 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/defaulted31.C @@ -0,0 +1,16 @@ +// PR c++/39164 +// { dg-options -std=c++0x } + +struct A +{ + A() { } // { dg-error "defined" } + ~A() = default; // { dg-error "defaulted" } +}; + +A::A() = default; // { dg-error "redefinition" } +A::~A() noexcept (true) { } // { dg-error "defaulted" } + +int main() +{ + A a; +} diff --git a/gcc/testsuite/g++.dg/warn/format5.C b/gcc/testsuite/g++.dg/warn/format5.C new file mode 100644 index 00000000000..e219f881092 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/format5.C @@ -0,0 +1,12 @@ +// PR c++/38980 +// { dg-options "-Wformat" } + +extern "C" +int printf(const char *format, ...) __attribute__((format(printf, 1, 2) )); + +const char fmt1[] = "Hello, %s"; + +void f() +{ + printf(fmt1, 3); // { dg-warning "expects argument" } +} diff --git a/gcc/testsuite/gcc.c-torture/compile/pr49049.c b/gcc/testsuite/gcc.c-torture/compile/pr49049.c new file mode 100644 index 00000000000..a24b2a41c75 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr49049.c @@ -0,0 +1,28 @@ +__extension__ typedef unsigned long long int uint64_t; + +static int +sub (int a, int b) +{ + return a - b; +} + +static uint64_t +add (uint64_t a, uint64_t b) +{ + return a + b; +} + +int *ptr; + +int +foo (uint64_t arg1, int *arg2) +{ + int j; + for (; j < 1; j++) + { + *arg2 |= sub ( sub (sub (j || 1 ^ 0x1, 1), arg1 < 0x1 <= + sub (1, *ptr & j)), + (sub ( j != 1 || sub (j && j, 1) >= 0, + add (!j > arg1, 0x35DLL)))); + } +} diff --git a/gcc/testsuite/gcc.c-torture/compile/pr50650.c b/gcc/testsuite/gcc.c-torture/compile/pr50650.c new file mode 100644 index 00000000000..6c443e6475c --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr50650.c @@ -0,0 +1,10 @@ +/* PR tree-optimization/50650 */ + +unsigned int +foo (unsigned int x, unsigned int y) +{ + int i; + for (i = 8; i--; x <<= 1) + y ^= (x ^ y) & 0x80 ? 79U : 0U; + return y; +} diff --git a/gcc/testsuite/gcc.c-torture/execute/pr49279.c b/gcc/testsuite/gcc.c-torture/execute/pr49279.c new file mode 100644 index 00000000000..7f2c0d22129 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr49279.c @@ -0,0 +1,35 @@ +/* PR tree-optimization/49279 */ +extern void abort (void); + +struct S { int a; int *__restrict p; }; + +__attribute__((noinline, noclone)) +struct S *bar (struct S *p) +{ + struct S *r; + asm volatile ("" : "=r" (r) : "0" (p) : "memory"); + return r; +} + +__attribute__((noinline, noclone)) +int +foo (int *p, int *q) +{ + struct S s, *t; + s.a = 1; + s.p = p; + t = bar (&s); + t->p = q; + s.p[0] = 0; + t->p[0] = 1; + return s.p[0]; +} + +int +main () +{ + int a, b; + if (foo (&a, &b) != 1) + abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.c-torture/execute/vect-shuffle-1.c b/gcc/testsuite/gcc.c-torture/execute/vect-shuffle-1.c deleted file mode 100644 index 3b836362003..00000000000 --- a/gcc/testsuite/gcc.c-torture/execute/vect-shuffle-1.c +++ /dev/null @@ -1,68 +0,0 @@ -#if __SIZEOF_INT__ == 4 -typedef unsigned int V __attribute__((vector_size(16), may_alias)); - -struct S -{ - V in, mask, out; -}; - -struct S tests[] = { - { - { 0x11111111, 0x22222222, 0x33333333, 0x44444444 }, - { 0, 1, 2, 3 }, - { 0x11111111, 0x22222222, 0x33333333, 0x44444444 }, - }, - { - { 0x11111111, 0x22222222, 0x33333333, 0x44444444 }, - { 0+1*4, 1+2*4, 2+3*4, 3+4*4 }, - { 0x11111111, 0x22222222, 0x33333333, 0x44444444 }, - }, - { - { 0x11111111, 0x22222222, 0x33333333, 0x44444444 }, - { 3, 2, 1, 0 }, - { 0x44444444, 0x33333333, 0x22222222, 0x11111111 }, - }, - { - { 0x11111111, 0x22222222, 0x33333333, 0x44444444 }, - { 0, 3, 2, 1 }, - { 0x11111111, 0x44444444, 0x33333333, 0x22222222 }, - }, - { - { 0x11111111, 0x22222222, 0x33333333, 0x44444444 }, - { 0, 2, 1, 3 }, - { 0x11111111, 0x33333333, 0x22222222, 0x44444444 }, - }, - { - { 0x11223344, 0x55667788, 0x99aabbcc, 0xddeeff00 }, - { 3, 1, 2, 0 }, - { 0xddeeff00, 0x55667788, 0x99aabbcc, 0x11223344 }, - }, - { - { 0x11223344, 0x55667788, 0x99aabbcc, 0xddeeff00 }, - { 0, 0, 0, 0 }, - { 0x11223344, 0x11223344, 0x11223344, 0x11223344 }, - }, - { - { 0x11223344, 0x55667788, 0x99aabbcc, 0xddeeff00 }, - { 1, 2, 1, 2 }, - { 0x55667788, 0x99aabbcc, 0x55667788, 0x99aabbcc }, - } -}; - -extern void abort(void); - -int main() -{ - int i; - - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); ++i) - { - V r = __builtin_shuffle(tests[i].in, tests[i].mask); - if (__builtin_memcmp(&r, &tests[i].out, sizeof(V)) != 0) - abort(); - } - - return 0; -} - -#endif /* SIZEOF_INT */ diff --git a/gcc/testsuite/gcc.c-torture/execute/vect-shuffle-2.c b/gcc/testsuite/gcc.c-torture/execute/vect-shuffle-2.c deleted file mode 100644 index 68ae2256f15..00000000000 --- a/gcc/testsuite/gcc.c-torture/execute/vect-shuffle-2.c +++ /dev/null @@ -1,68 +0,0 @@ -#if __SIZEOF_SHORT__ == 2 -typedef unsigned short V __attribute__((vector_size(16), may_alias)); - -struct S -{ - V in, mask, out; -}; - -struct S tests[] = { - { - { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0x8888 }, - { 0, 1, 2, 3, 4, 5, 6, 7 }, - { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0x8888 }, - }, - { - { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0x8888 }, - { 0x10, 0x21, 0x32, 0x43, 0x54, 0x65, 0x76, 0x87 }, - { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0x8888 }, - }, - { - { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0x8888 }, - { 7, 6, 5, 4, 3, 2, 1, 0 }, - { 0x8888, 0x7777, 0x6666, 0x5555, 0x4444, 0x3333, 0x2222, 0x1111 }, - }, - { - { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0x8888 }, - { 7, 0, 5, 3, 2, 4, 1, 6 }, - { 0x8888, 0x1111, 0x6666, 0x4444, 0x3333, 0x5555, 0x2222, 0x7777 }, - }, - { - { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0x8888 }, - { 0, 2, 1, 3, 4, 6, 5, 7 }, - { 0x1111, 0x3333, 0x2222, 0x4444, 0x5555, 0x7777, 0x6666, 0x8888 }, - }, - { - { 0x1122, 0x3344, 0x5566, 0x7788, 0x99aa, 0xbbcc, 0xddee, 0xff00 }, - { 3, 1, 2, 0, 7, 5, 6, 4 }, - { 0x7788, 0x3344, 0x5566, 0x1122, 0xff00, 0xbbcc, 0xddee, 0x99aa }, - }, - { - { 0x1122, 0x3344, 0x5566, 0x7788, 0x99aa, 0xbbcc, 0xddee, 0xff00 }, - { 0, 0, 0, 0 }, - { 0x1122, 0x1122, 0x1122, 0x1122, 0x1122, 0x1122, 0x1122, 0x1122 }, - }, - { - { 0x1122, 0x3344, 0x5566, 0x7788, 0x99aa, 0xbbcc, 0xddee, 0xff00 }, - { 1, 6, 1, 6, 1, 6, 1, 6 }, - { 0x3344, 0xddee, 0x3344, 0xddee, 0x3344, 0xddee, 0x3344, 0xddee }, - } -}; - -extern void abort(void); - -int main() -{ - int i; - - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); ++i) - { - V r = __builtin_shuffle(tests[i].in, tests[i].mask); - if (memcmp(&r, &tests[i].out, sizeof(V)) != 0) - abort(); - } - - return 0; -} - -#endif /* SIZEOF_SHORT */ diff --git a/gcc/testsuite/gcc.c-torture/execute/vect-shuffle-3.c b/gcc/testsuite/gcc.c-torture/execute/vect-shuffle-3.c deleted file mode 100644 index 96aee650994..00000000000 --- a/gcc/testsuite/gcc.c-torture/execute/vect-shuffle-3.c +++ /dev/null @@ -1,58 +0,0 @@ -#if __SIZEOF_LONG_LONG__ == 8 -typedef unsigned long long V __attribute__((vector_size(16), may_alias)); - -struct S -{ - V in, mask, out; -}; - -struct S tests[] = { - { - { 0x1111111111111111, 0x2222222222222222 }, - { 0, 1 }, - { 0x1111111111111111, 0x2222222222222222 }, - }, - { - { 0x1111111111111111, 0x2222222222222222 }, - { 0x0102030405060700, 0xffeeddccbbaa99f1 }, - { 0x1111111111111111, 0x2222222222222222 }, - }, - { - { 0x1111111111111111, 0x2222222222222222 }, - { 1, 0 }, - { 0x2222222222222222, 0x1111111111111111 }, - }, - { - { 0x1111111111111111, 0x2222222222222222 }, - { 0, 0 }, - { 0x1111111111111111, 0x1111111111111111 }, - }, - { - { 0x1122334455667788, 0x99aabbccddeeff00 }, - { 1, 1 }, - { 0x99aabbccddeeff00, 0x99aabbccddeeff00 }, - }, - { - { 0x1122334455667788, 0x99aabbccddeeff00 }, - { 1, 0 }, - { 0x99aabbccddeeff00, 0x1122334455667788 }, - }, -}; - -extern void abort(void); - -int main() -{ - int i; - - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); ++i) - { - V r = __builtin_shuffle(tests[i].in, tests[i].mask); - if (__builtin_memcmp(&r, &tests[i].out, sizeof(V)) != 0) - abort(); - } - - return 0; -} - -#endif /* SIZEOF_LONG_LONG */ diff --git a/gcc/testsuite/gcc.c-torture/execute/vect-shuffle-4.c b/gcc/testsuite/gcc.c-torture/execute/vect-shuffle-4.c deleted file mode 100644 index fa036eb0093..00000000000 --- a/gcc/testsuite/gcc.c-torture/execute/vect-shuffle-4.c +++ /dev/null @@ -1,51 +0,0 @@ -typedef unsigned char V __attribute__((vector_size(16), may_alias)); - -struct S -{ - V in, mask, out; -}; - -struct S tests[] = { - { - { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }, - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, }, - { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }, - }, - { - { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }, - { 0x10, 0x21, 0x32, 0x43, 0x54, 0x65, 0x76, 0x87, - 0x98, 0xa9, 0xba, 0xcb, 0xdc, 0xed, 0xfe, 0xff }, - { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }, - }, - { - { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }, - { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }, - { 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 }, - }, - { - { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }, - { 0, 2, 4, 6, 8, 10, 12, 14, 1, 3, 5, 7, 9, 11, 13, 15 }, - { 1, 3, 5, 7, 9, 11, 13, 15, 2, 4, 6, 8, 10, 12, 14, 16 }, - }, - { - { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }, - { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, - { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 }, - }, -}; - -extern void abort(void); - -int main() -{ - int i; - - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); ++i) - { - V r = __builtin_shuffle(tests[i].in, tests[i].mask); - if (memcmp(&r, &tests[i].out, sizeof(V)) != 0) - abort(); - } - - return 0; -} diff --git a/gcc/testsuite/gcc.c-torture/execute/vect-shuffle-5.c b/gcc/testsuite/gcc.c-torture/execute/vect-shuffle-5.c deleted file mode 100644 index f07025d567e..00000000000 --- a/gcc/testsuite/gcc.c-torture/execute/vect-shuffle-5.c +++ /dev/null @@ -1,64 +0,0 @@ -#if __SIZEOF_INT__ == 4 -typedef unsigned int V __attribute__((vector_size(16), may_alias)); - -struct S -{ - V in1, in2, mask, out; -}; - -struct S tests[] = { - { - { 0x11111111, 0x22222222, 0x33333333, 0x44444444 }, - { 0x55555555, 0x66666666, 0x77777777, 0x88888888 }, - { 0, 1, 2, 3 }, - { 0x11111111, 0x22222222, 0x33333333, 0x44444444 }, - }, - { - { 0x11111111, 0x22222222, 0x33333333, 0x44444444 }, - { 0x55555555, 0x66666666, 0x77777777, 0x88888888 }, - { 4, 5, 6, 7 }, - { 0x55555555, 0x66666666, 0x77777777, 0x88888888 }, - }, - { - { 0x11111111, 0x22222222, 0x33333333, 0x44444444 }, - { 0x55555555, 0x66666666, 0x77777777, 0x88888888 }, - { 0, 4, 1, 5 }, - { 0x11111111, 0x55555555, 0x22222222, 0x66666666 }, - }, - { - { 0x11111111, 0x22222222, 0x33333333, 0x44444444 }, - { 0x55555555, 0x66666666, 0x77777777, 0x88888888 }, - { 0, 7, 4, 3 }, - { 0x11111111, 0x88888888, 0x55555555, 0x44444444 }, - }, - { - { 0x11111111, 0x22222222, 0x33333333, 0x44444444 }, - { 0x55555555, 0x66666666, 0x77777777, 0x88888888 }, - { 0, 0, 0, 0 }, - { 0x11111111, 0x11111111, 0x11111111, 0x11111111 }, - }, - { - { 0x11111111, 0x22222222, 0x33333333, 0x44444444 }, - { 0x55555555, 0x66666666, 0x77777777, 0x88888888 }, - { 7, 7, 7, 7 }, - { 0x88888888, 0x88888888, 0x88888888, 0x88888888 }, - }, -}; - -extern void abort(void); - -int main() -{ - int i; - - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); ++i) - { - V r = __builtin_shuffle(tests[i].in1, tests[i].in2, tests[i].mask); - if (__builtin_memcmp(&r, &tests[i].out, sizeof(V)) != 0) - abort(); - } - - return 0; -} - -#endif /* SIZEOF_INT */ diff --git a/gcc/testsuite/gcc.c-torture/execute/vect-shuffle-6.c b/gcc/testsuite/gcc.c-torture/execute/vect-shuffle-6.c deleted file mode 100644 index 63eaf96900e..00000000000 --- a/gcc/testsuite/gcc.c-torture/execute/vect-shuffle-6.c +++ /dev/null @@ -1,64 +0,0 @@ -#if __SIZEOF_SHORT__ == 2 -typedef unsigned short V __attribute__((vector_size(16), may_alias)); - -struct S -{ - V in1, in2, mask, out; -}; - -struct S tests[] = { - { - { 0x1010, 0x2121, 0x3232, 0x4343, 0x5454, 0x6565, 0x7676, 0x8787 }, - { 0x9898, 0xa9a9, 0xbaba, 0xcbcb, 0xdcdc, 0xeded, 0xfefe, 0x0f0f }, - { 0, 1, 2, 3, 4, 5, 6, 7 }, - { 0x1010, 0x2121, 0x3232, 0x4343, 0x5454, 0x6565, 0x7676, 0x8787 }, - }, - { - { 0x1010, 0x2121, 0x3232, 0x4343, 0x5454, 0x6565, 0x7676, 0x8787 }, - { 0x9898, 0xa9a9, 0xbaba, 0xcbcb, 0xdcdc, 0xeded, 0xfefe, 0x0f0f }, - { 8, 9, 10, 11, 12, 13, 14, 15 }, - { 0x9898, 0xa9a9, 0xbaba, 0xcbcb, 0xdcdc, 0xeded, 0xfefe, 0x0f0f }, - }, - { - { 0x1010, 0x2121, 0x3232, 0x4343, 0x5454, 0x6565, 0x7676, 0x8787 }, - { 0x9898, 0xa9a9, 0xbaba, 0xcbcb, 0xdcdc, 0xeded, 0xfefe, 0x0f0f }, - { 0, 8, 1, 9, 2, 10, 3, 11 }, - { 0x1010, 0x9898, 0x2121, 0xa9a9, 0x3232, 0xbaba, 0x4343, 0xcbcb }, - }, - { - { 0x1010, 0x2121, 0x3232, 0x4343, 0x5454, 0x6565, 0x7676, 0x8787 }, - { 0x9898, 0xa9a9, 0xbaba, 0xcbcb, 0xdcdc, 0xeded, 0xfefe, 0x0f0f }, - { 0, 15, 4, 11, 12, 3, 7, 8 }, - { 0x1010, 0x0f0f, 0x5454, 0xcbcb, 0xdcdc, 0x4343, 0x8787, 0x9898 }, - }, - { - { 0x1010, 0x2121, 0x3232, 0x4343, 0x5454, 0x6565, 0x7676, 0x8787 }, - { 0x9898, 0xa9a9, 0xbaba, 0xcbcb, 0xdcdc, 0xeded, 0xfefe, 0x0f0f }, - { 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0x1010, 0x1010, 0x1010, 0x1010, 0x1010, 0x1010, 0x1010, 0x1010 }, - }, - { - { 0x1010, 0x2121, 0x3232, 0x4343, 0x5454, 0x6565, 0x7676, 0x8787 }, - { 0x9898, 0xa9a9, 0xbaba, 0xcbcb, 0xdcdc, 0xeded, 0xfefe, 0x0f0f }, - { 14, 14, 14, 14, 14, 14, 14, 14 }, - { 0xfefe, 0xfefe, 0xfefe, 0xfefe, 0xfefe, 0xfefe, 0xfefe, 0xfefe }, - }, -}; - -extern void abort(void); - -int main() -{ - int i; - - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); ++i) - { - V r = __builtin_shuffle(tests[i].in1, tests[i].in2, tests[i].mask); - if (__builtin_memcmp(&r, &tests[i].out, sizeof(V)) != 0) - abort(); - } - - return 0; -} - -#endif /* SIZEOF_SHORT */ diff --git a/gcc/testsuite/gcc.c-torture/execute/vect-shuffle-7.c b/gcc/testsuite/gcc.c-torture/execute/vect-shuffle-7.c deleted file mode 100644 index 3336c6f7bd5..00000000000 --- a/gcc/testsuite/gcc.c-torture/execute/vect-shuffle-7.c +++ /dev/null @@ -1,70 +0,0 @@ -#if __SIZEOF_LONG_LONG__ == 8 -typedef unsigned long long V __attribute__((vector_size(16), may_alias)); - -struct S -{ - V in1, in2, mask, out; -}; - -struct S tests[] = { - { - { 0x1112131415161718, 0x2122232425262728 }, - { 0x3132333435363738, 0x4142434445464748 }, - { 0, 1 }, - { 0x1112131415161718, 0x2122232425262728 }, - }, - { - { 0x1112131415161718, 0x2122232425262728 }, - { 0x3132333435363738, 0x4142434445464748 }, - { 2, 3 }, - { 0x3132333435363738, 0x4142434445464748 }, - }, - { - { 0x1112131415161718, 0x2122232425262728 }, - { 0x3132333435363738, 0x4142434445464748 }, - { 0, 2 }, - { 0x1112131415161718, 0x3132333435363738 }, - }, - { - { 0x1112131415161718, 0x2122232425262728 }, - { 0x3132333435363738, 0x4142434445464748 }, - { 2, 1 }, - { 0x3132333435363738, 0x2122232425262728 }, - }, - { - { 0x1112131415161718, 0x2122232425262728 }, - { 0x3132333435363738, 0x4142434445464748 }, - { 3, 0 }, - { 0x4142434445464748, 0x1112131415161718 }, - }, - { - { 0x1112131415161718, 0x2122232425262728 }, - { 0x3132333435363738, 0x4142434445464748 }, - { 0, 0 }, - { 0x1112131415161718, 0x1112131415161718 }, - }, - { - { 0x1112131415161718, 0x2122232425262728 }, - { 0x3132333435363738, 0x4142434445464748 }, - { 3, 3 }, - { 0x4142434445464748, 0x4142434445464748 }, - }, -}; - -extern void abort(void); - -int main() -{ - int i; - - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); ++i) - { - V r = __builtin_shuffle(tests[i].in1, tests[i].in2, tests[i].mask); - if (__builtin_memcmp(&r, &tests[i].out, sizeof(V)) != 0) - abort(); - } - - return 0; -} - -#endif /* SIZEOF_LONG_LONG */ diff --git a/gcc/testsuite/gcc.c-torture/execute/vector-compare-2.x b/gcc/testsuite/gcc.c-torture/execute/vector-compare-2.x new file mode 100644 index 00000000000..cb7b119b8cb --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/vector-compare-2.x @@ -0,0 +1,2 @@ +set additional_flags "-Wno-psabi" +return 0 diff --git a/gcc/testsuite/gcc.c-torture/execute/vect-shuffle-8.c b/gcc/testsuite/gcc.c-torture/execute/vshuf-16.inc index f98e6ec99e2..68f2646d860 100644 --- a/gcc/testsuite/gcc.c-torture/execute/vect-shuffle-8.c +++ b/gcc/testsuite/gcc.c-torture/execute/vshuf-16.inc @@ -1,12 +1,52 @@ -typedef unsigned char V __attribute__((vector_size(16), may_alias)); +/* Test fragment for vectors with 16 elements. */ + +#ifndef UNSUPPORTED struct S { - V in1, in2, mask, out; + V in; + VI mask; + V out; }; struct S tests[] = { { + { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, }, + { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }, + }, + { + { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }, + { 0x10, 0x21, 0x32, 0x43, 0x54, 0x65, 0x76, 0x87, + 0x98, 0xa9, 0xba, 0xcb, 0xdc, 0xed, 0xfe, 0xff }, + { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }, + }, + { + { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }, + { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }, + { 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 }, + }, + { + { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }, + { 0, 2, 4, 6, 8, 10, 12, 14, 1, 3, 5, 7, 9, 11, 13, 15 }, + { 1, 3, 5, 7, 9, 11, 13, 15, 2, 4, 6, 8, 10, 12, 14, 16 }, + }, + { + { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }, + { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, + { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 }, + }, +}; + +struct S2 +{ + V in1, in2; + VI mask; + V out; +}; + +struct S2 tests2[] = { + { { 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 }, { 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45 }, { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, @@ -38,18 +78,4 @@ struct S tests[] = { }, }; -extern void abort(void); - -int main() -{ - int i; - - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); ++i) - { - V r = __builtin_shuffle(tests[i].in1, tests[i].in2, tests[i].mask); - if (__builtin_memcmp(&r, &tests[i].out, sizeof(V)) != 0) - abort(); - } - - return 0; -} +#endif diff --git a/gcc/testsuite/gcc.c-torture/execute/vshuf-2.inc b/gcc/testsuite/gcc.c-torture/execute/vshuf-2.inc new file mode 100644 index 00000000000..ef778e59418 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/vshuf-2.inc @@ -0,0 +1,38 @@ +/* Test fragment for vectors of 2 elements. */ + +#ifndef UNSUPPORTED + +struct S +{ + V in; + VI mask; + V out; +}; + +struct S tests[] = { + { { A, B }, { 0, 1 }, { A, B } }, + { { A, B }, { -16, -1 }, { A, B } }, + { { A, B }, { 1, 0 }, { B, A } }, + { { A, B }, { 0, 0 }, { A, A } }, + { { X, Y }, { 1, 1 }, { Y, Y } }, + { { X, Y }, { 1, 0 }, { Y, X } }, +}; + +struct S2 +{ + V in1, in2; + VI mask; + V out; +}; + +struct S2 tests2[] = { + { { A, B }, { X, Y }, { 0, 1 }, { A, B } }, + { { A, B }, { X, Y }, { 2, 3 }, { X, Y } }, + { { A, B }, { X, Y }, { 0, 2 }, { A, X } }, + { { A, B }, { X, Y }, { 2, 1 }, { X, B } }, + { { A, B }, { X, Y }, { 3, 0 }, { Y, A } }, + { { A, B }, { X, Y }, { 0, 0 }, { A, A } }, + { { A, B }, { X, Y }, { 3, 3 }, { Y, Y } }, +}; + +#endif diff --git a/gcc/testsuite/gcc.c-torture/execute/vshuf-4.inc b/gcc/testsuite/gcc.c-torture/execute/vshuf-4.inc new file mode 100644 index 00000000000..d6e6e102295 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/vshuf-4.inc @@ -0,0 +1,39 @@ +/* Test fragment for vectors of 4 elements. */ + +#ifndef UNSUPPORTED + +struct S +{ + V in; + VI mask; + V out; +}; + +struct S tests[] = { + { { A, B, C, D }, { 0, 1, 2, 3 }, { A, B, C, D }, }, + { { A, B, C, D }, { 0+1*4, 1+2*4, 2+3*4, 3+4*4 }, { A, B, C, D } }, + { { A, B, C, D }, { 3, 2, 1, 0 }, { D, C, B, A } }, + { { A, B, C, D }, { 0, 3, 2, 1 }, { A, D, C, B } }, + { { A, B, C, D }, { 0, 2, 1, 3 }, { A, C, B, D } }, + { { W, X, Y, Z }, { 3, 1, 2, 0 }, { Z, X, Y, W } }, + { { W, X, Y, Z }, { 0, 0, 0, 0 }, { W, W, W, W } }, + { { W, X, Y, Z }, { 1, 2, 1, 2 }, { X, Y, X, Y } }, +}; + +struct S2 +{ + V in1, in2; + VI mask; + V out; +}; + +struct S2 tests2[] = { + { { A, B, C, D }, { W, X, Y, Z }, { 0, 1, 2, 3 }, { A, B, C, D } }, + { { A, B, C, D }, { W, X, Y, Z }, { 4, 5, 6, 7 }, { W, X, Y, Z } }, + { { A, B, C, D }, { W, X, Y, Z }, { 0, 4, 1, 5 }, { A, W, B, X } }, + { { A, B, C, D }, { W, X, Y, Z }, { 0, 7, 4, 3 }, { A, Z, W, D } }, + { { A, B, C, D }, { W, X, Y, Z }, { 0, 0, 0, 0 }, { A, A, A, A } }, + { { A, B, C, D }, { W, X, Y, Z }, { 7, 7, 7, 7 }, { Z, Z, Z, Z } }, +}; + +#endif diff --git a/gcc/testsuite/gcc.c-torture/execute/vshuf-8.inc b/gcc/testsuite/gcc.c-torture/execute/vshuf-8.inc new file mode 100644 index 00000000000..e6475226a11 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/vshuf-8.inc @@ -0,0 +1,101 @@ +/* Test fragment for vectors of 8 elements. */ + +#ifndef UNSUPPORTED + +struct S +{ + V in; + VI mask; + V out; +}; + +struct S tests[] = { + { + { A1, B1, C1, D1, E1, F1, G1, H1 }, + { 0, 1, 2, 3, 4, 5, 6, 7 }, + { A1, B1, C1, D1, E1, F1, G1, H1 }, + }, + { + { A1, B1, C1, D1, E1, F1, G1, H1 }, + { 0x10, 0x21, 0x32, 0x43, 0x54, 0x65, 0x76, 0x87 }, + { A1, B1, C1, D1, E1, F1, G1, H1 }, + }, + { + { A1, B1, C1, D1, E1, F1, G1, H1 }, + { 7, 6, 5, 4, 3, 2, 1, 0 }, + { H1, G1, F1, E1, D1, C1, B1, A1 }, + }, + { + { A1, B1, C1, D1, E1, F1, G1, H1 }, + { 7, 0, 5, 3, 2, 4, 1, 6 }, + { H1, A1, F1, D1, C1, E1, B1, G1 }, + }, + { + { A1, B1, C1, D1, E1, F1, G1, H1 }, + { 0, 2, 1, 3, 4, 6, 5, 7 }, + { A1, C1, B1, D1, E1, G1, F1, H1 }, + }, + { + { A2, B2, C2, D2, E2, F2, G2, H2 }, + { 3, 1, 2, 0, 7, 5, 6, 4 }, + { D2, B2, C2, A2, H2, F2, G2, E2 }, + }, + { + { A2, B2, C2, D2, E2, F2, G2, H2 }, + { 0, 0, 0, 0 }, + { A2, A2, A2, A2, A2, A2, A2, A2 }, + }, + { + { A2, B2, C2, D2, E2, F2, G2, H2 }, + { 1, 6, 1, 6, 1, 6, 1, 6 }, + { B2, G2, B2, G2, B2, G2, B2, G2 }, + } +}; + +struct S2 +{ + V in1, in2; + VI mask; + V out; +}; + +struct S2 tests2[] = { + { + { A1, B1, C1, D1, E1, F1, G1, H1 }, + { A2, B2, C2, D2, E2, F2, G2, H2 }, + { 0, 1, 2, 3, 4, 5, 6, 7 }, + { A1, B1, C1, D1, E1, F1, G1, H1 }, + }, + { + { A1, B1, C1, D1, E1, F1, G1, H1 }, + { A2, B2, C2, D2, E2, F2, G2, H2 }, + { 8, 9, 10, 11, 12, 13, 14, 15 }, + { A2, B2, C2, D2, E2, F2, G2, H2 }, + }, + { + { A1, B1, C1, D1, E1, F1, G1, H1 }, + { A2, B2, C2, D2, E2, F2, G2, H2 }, + { 0, 8, 1, 9, 2, 10, 3, 11 }, + { A1, A2, B1, B2, C1, C2, D1, D2 }, + }, + { + { A1, B1, C1, D1, E1, F1, G1, H1 }, + { A2, B2, C2, D2, E2, F2, G2, H2 }, + { 0, 15, 4, 11, 12, 3, 7, 8 }, + { A1, H2, E1, D2, E2, D1, H1, A2 }, + }, + { + { A1, B1, C1, D1, E1, F1, G1, H1 }, + { A2, B2, C2, D2, E2, F2, G2, H2 }, + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { A1, A1, A1, A1, A1, A1, A1, A1 }, + }, + { + { A1, B1, C1, D1, E1, F1, G1, H1 }, + { A2, B2, C2, D2, E2, F2, G2, H2 }, + { 0x1e, 0x2e, 0x3e, 0x4e, 0x5e, 0x6e, 0x7e, 0x8e }, + { G2, G2, G2, G2, G2, G2, G2, G2 }, + }, +}; + +#endif diff --git a/gcc/testsuite/gcc.c-torture/execute/vshuf-main.inc b/gcc/testsuite/gcc.c-torture/execute/vshuf-main.inc new file mode 100644 index 00000000000..8487131b12d --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/vshuf-main.inc @@ -0,0 +1,26 @@ +/* Driver fragment for __builtin_shuffle of any vector shape. */ + +extern void abort(void); + +int main() +{ +#ifndef UNSUPPORTED + int i; + + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); ++i) + { + V r = __builtin_shuffle(tests[i].in, tests[i].mask); + if (__builtin_memcmp(&r, &tests[i].out, sizeof(V)) != 0) + abort(); + } + + for (i = 0; i < sizeof(tests2)/sizeof(tests2[0]); ++i) + { + V r = __builtin_shuffle(tests2[i].in1, tests2[i].in2, tests2[i].mask); + if (__builtin_memcmp(&r, &tests2[i].out, sizeof(V)) != 0) + abort(); + } +#endif + + return 0; +} diff --git a/gcc/testsuite/gcc.c-torture/execute/vshuf-v16qi.c b/gcc/testsuite/gcc.c-torture/execute/vshuf-v16qi.c new file mode 100644 index 00000000000..dcd1de1e646 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/vshuf-v16qi.c @@ -0,0 +1,5 @@ +typedef unsigned char V __attribute__((vector_size(16))); +typedef V VI; + +#include "vshuf-16.inc" +#include "vshuf-main.inc" diff --git a/gcc/testsuite/gcc.c-torture/execute/vshuf-v2df.c b/gcc/testsuite/gcc.c-torture/execute/vshuf-v2df.c new file mode 100644 index 00000000000..e88ec08ddf6 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/vshuf-v2df.c @@ -0,0 +1,15 @@ +#if __SIZEOF_DOUBLE__ == 8 && __SIZEOF_LONG_LONG__ == 8 +typedef double V __attribute__((vector_size(16))); +typedef unsigned long long VI __attribute__((vector_size(16))); +#else +#define UNSUPPORTED +#endif + +#define A 0.69314718055994530942 +#define B 2.7182818284590452354 + +#define X 3.14159265358979323846 +#define Y 1.41421356237309504880 + +#include "vshuf-2.inc" +#include "vshuf-main.inc" diff --git a/gcc/testsuite/gcc.c-torture/execute/vshuf-v2di.c b/gcc/testsuite/gcc.c-torture/execute/vshuf-v2di.c new file mode 100644 index 00000000000..0985a0de02a --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/vshuf-v2di.c @@ -0,0 +1,15 @@ +#if __SIZEOF_LONG_LONG__ == 8 +typedef unsigned long long V __attribute__((vector_size(16))); +typedef V VI; +#else +#define UNSUPPORTED +#endif + +#define A 0x1112131415161718 +#define B 0x2122232425262728 + +#define X 0xc1c2c3c4c5c6c7c8 +#define Y 0xd1d2d3d4d5d6d7d8 + +#include "vshuf-2.inc" +#include "vshuf-main.inc" diff --git a/gcc/testsuite/gcc.c-torture/execute/vshuf-v2sf.c b/gcc/testsuite/gcc.c-torture/execute/vshuf-v2sf.c new file mode 100644 index 00000000000..f9c40b22391 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/vshuf-v2sf.c @@ -0,0 +1,21 @@ +#if __SIZEOF_FLOAT__ == 4 +typedef float V __attribute__((vector_size(8))); +# if __SIZEOF_INT__ == 4 +typedef unsigned int VI __attribute__((vector_size(8))); +# elif __SIZEOF_LONG__ == 4 +typedef unsigned long VI __attribute__((vector_size(8))); +# else +# define UNSUPPORTED +# endif +#else +# define UNSUPPORTED +#endif + +#define A 0.69314718055994530942f +#define B 2.7182818284590452354f + +#define X 3.14159265358979323846f +#define Y 1.41421356237309504880f + +#include "vshuf-2.inc" +#include "vshuf-main.inc" diff --git a/gcc/testsuite/gcc.c-torture/execute/vshuf-v2si.c b/gcc/testsuite/gcc.c-torture/execute/vshuf-v2si.c new file mode 100644 index 00000000000..414743c892f --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/vshuf-v2si.c @@ -0,0 +1,18 @@ +#if __SIZEOF_INT__ == 4 +typedef unsigned int V __attribute__((vector_size(8))); +typedef V VI; +#elif __SIZEOF_LONG__ == 4 +typedef unsigned long V __attribute__((vector_size(8))); +typedef V VI; +#else +#define UNSUPPORTED +#endif + +#define A 0x11121314 +#define B 0x21222324 + +#define X 0xd1d2d3d4 +#define Y 0xe1e2e3e4 + +#include "vshuf-2.inc" +#include "vshuf-main.inc" diff --git a/gcc/testsuite/gcc.c-torture/execute/vshuf-v4df.c b/gcc/testsuite/gcc.c-torture/execute/vshuf-v4df.c new file mode 100644 index 00000000000..c4030a7dbab --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/vshuf-v4df.c @@ -0,0 +1,19 @@ +#if __SIZEOF_DOUBLE__ == 8 && __SIZEOF_LONG_LONG__ == 8 +typedef double V __attribute__((vector_size(32))); +typedef unsigned long long VI __attribute__((vector_size(32))); +#else +#define UNSUPPORTED +#endif + +#define A 0.69314718055994530942 +#define B 2.7182818284590452354 +#define C 2.30258509299404568402 +#define D 1.4426950408889634074 + +#define W 0.31830988618379067154 +#define X 3.14159265358979323846 +#define Y 1.41421356237309504880 +#define Z 0.70710678118654752440 + +#include "vshuf-4.inc" +#include "vshuf-main.inc" diff --git a/gcc/testsuite/gcc.c-torture/execute/vshuf-v4di.c b/gcc/testsuite/gcc.c-torture/execute/vshuf-v4di.c new file mode 100644 index 00000000000..a84aebefb6d --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/vshuf-v4di.c @@ -0,0 +1,19 @@ +#if __SIZEOF_LONG_LONG__ == 8 +typedef unsigned long long V __attribute__((vector_size(32))); +typedef V VI; +#else +#define UNSUPPORTED +#endif + +#define A 0x1112131415161718 +#define B 0x2122232425262728 +#define C 0x3132333435363738 +#define D 0x4142434445464748 + +#define W 0xc1c2c3c4c5c6c7c8 +#define X 0xd1d2d3d4d5d6d7d8 +#define Y 0xe1e2e3e4e5e6e7e8 +#define Z 0xf1f2f3f4f5f6f7f8 + +#include "vshuf-4.inc" +#include "vshuf-main.inc" diff --git a/gcc/testsuite/gcc.c-torture/execute/vshuf-v4hi.c b/gcc/testsuite/gcc.c-torture/execute/vshuf-v4hi.c new file mode 100644 index 00000000000..64a2bb4ac82 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/vshuf-v4hi.c @@ -0,0 +1,15 @@ +typedef unsigned short V __attribute__((vector_size(8))); +typedef V VI; + +#define A 0x1112 +#define B 0x2122 +#define C 0x3132 +#define D 0x4142 + +#define W 0xc1c2 +#define X 0xd1d2 +#define Y 0xe1e2 +#define Z 0xf1f2 + +#include "vshuf-4.inc" +#include "vshuf-main.inc" diff --git a/gcc/testsuite/gcc.c-torture/execute/vshuf-v4sf.c b/gcc/testsuite/gcc.c-torture/execute/vshuf-v4sf.c new file mode 100644 index 00000000000..283672560a3 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/vshuf-v4sf.c @@ -0,0 +1,25 @@ +#if __SIZEOF_FLOAT__ == 4 +typedef float V __attribute__((vector_size(16))); +# if __SIZEOF_INT__ == 4 +typedef unsigned int VI __attribute__((vector_size(16))); +# elif __SIZEOF_LONG__ == 4 +typedef unsigned long VI __attribute__((vector_size(16))); +# else +# define UNSUPPORTED +# endif +#else +# define UNSUPPORTED +#endif + +#define A 0.69314718055994530942f +#define B 2.7182818284590452354f +#define C 2.30258509299404568402f +#define D 1.4426950408889634074f + +#define W 0.31830988618379067154f +#define X 3.14159265358979323846f +#define Y 1.41421356237309504880f +#define Z 0.70710678118654752440f + +#include "vshuf-4.inc" +#include "vshuf-main.inc" diff --git a/gcc/testsuite/gcc.c-torture/execute/vshuf-v4si.c b/gcc/testsuite/gcc.c-torture/execute/vshuf-v4si.c new file mode 100644 index 00000000000..289ec1b5016 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/vshuf-v4si.c @@ -0,0 +1,22 @@ +#if __SIZEOF_INT__ == 4 +typedef unsigned int V __attribute__((vector_size(16))); +typedef V VI; +#elif __SIZEOF_LONG__ == 4 +typedef unsigned long V __attribute__((vector_size(16))); +typedef V VI; +#else +# define UNSUPPORTED +#endif + +#define A 0x11121314 +#define B 0x21222324 +#define C 0x31323334 +#define D 0x41424344 + +#define W 0xc1c2c3c4 +#define X 0xd1d2d3d4 +#define Y 0xe1e2e3e4 +#define Z 0xf1f2f3f4 + +#include "vshuf-4.inc" +#include "vshuf-main.inc" diff --git a/gcc/testsuite/gcc.c-torture/execute/vshuf-v8hi.c b/gcc/testsuite/gcc.c-torture/execute/vshuf-v8hi.c new file mode 100644 index 00000000000..ce442c5d995 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/vshuf-v8hi.c @@ -0,0 +1,23 @@ +typedef unsigned short V __attribute__((vector_size(16))); +typedef V VI; + +#define A1 0x1112 +#define B1 0x2122 +#define C1 0x3132 +#define D1 0x4142 +#define E1 0x5152 +#define F1 0x6162 +#define G1 0x7172 +#define H1 0x8182 + +#define A2 0x9192 +#define B2 0xa1a2 +#define C2 0xb1b2 +#define D2 0xc1c2 +#define E2 0xd1d2 +#define F2 0xe1e2 +#define G2 0xf1f2 +#define H2 0x0102 + +#include "vshuf-8.inc" +#include "vshuf-main.inc" diff --git a/gcc/testsuite/gcc.c-torture/execute/vshuf-v8qi.c b/gcc/testsuite/gcc.c-torture/execute/vshuf-v8qi.c new file mode 100644 index 00000000000..349ec6db699 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/vshuf-v8qi.c @@ -0,0 +1,23 @@ +typedef unsigned char V __attribute__((vector_size(8))); +typedef V VI; + +#define A1 0x11 +#define B1 0x12 +#define C1 0x13 +#define D1 0x14 +#define E1 0x15 +#define F1 0x16 +#define G1 0x17 +#define H1 0x18 + +#define A2 0xf1 +#define B2 0xf2 +#define C2 0xf3 +#define D2 0xf4 +#define E2 0xf5 +#define F2 0xf6 +#define G2 0xf7 +#define H2 0xf8 + +#include "vshuf-8.inc" +#include "vshuf-main.inc" diff --git a/gcc/testsuite/gcc.c-torture/execute/vshuf-v8si.c b/gcc/testsuite/gcc.c-torture/execute/vshuf-v8si.c new file mode 100644 index 00000000000..5b0a2c33e2c --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/vshuf-v8si.c @@ -0,0 +1,30 @@ +#if __SIZEOF_INT__ == 4 +typedef unsigned int V __attribute__((vector_size(32))); +typedef V VI; +#elif __SIZEOF_LONG__ == 4 +typedef unsigned long V __attribute__((vector_size(32))); +typedef V VI; +#else +# define UNSUPPORTED +#endif + +#define A1 0x11121314 +#define B1 0x21222324 +#define C1 0x31323334 +#define D1 0x41424344 +#define E1 0x51525354 +#define F1 0x61626364 +#define G1 0x71727374 +#define H1 0x81828384 + +#define A2 0x91929394 +#define B2 0xa1a2a3a4 +#define C2 0xb1b2b3b4 +#define D2 0xc1c2c3c4 +#define E2 0xd1d2d3d4 +#define F2 0xe1e2e3e4 +#define G2 0xf1f2f3f4 +#define H2 0x01020304 + +#include "vshuf-8.inc" +#include "vshuf-main.inc" diff --git a/gcc/testsuite/gcc.dg/lto/20081222_1.c b/gcc/testsuite/gcc.dg/lto/20081222_1.c index e8f9254421b..755eb9918e9 100644 --- a/gcc/testsuite/gcc.dg/lto/20081222_1.c +++ b/gcc/testsuite/gcc.dg/lto/20081222_1.c @@ -1,8 +1,12 @@ #include "20081222_0.h" +#define ASMNAME(cname) ASMNAME2 (__USER_LABEL_PREFIX__, cname) +#define ASMNAME2(prefix, cname) STRING (prefix) cname +#define STRING(x) #x + /* Actually, call "x" "INT_X", and make it hidden. */ extern __typeof (x) x - __asm__ ("INT_x") + __asm__ (ASMNAME ("INT_x")) __attribute__ ((__visibility__ ("hidden"))); int x () @@ -12,5 +16,5 @@ int x () /* Make an externally-visible symbol "X" that's an alias for INT_x. */ extern __typeof (x) EXT_x - __asm__ ("x") + __asm__ (ASMNAME ("x")) __attribute__ ((__alias__ ("INT_x"))); diff --git a/gcc/testsuite/gcc.dg/pr47276.c b/gcc/testsuite/gcc.dg/pr47276.c index 3fa1a0e49a8..9276b1a6854 100644 --- a/gcc/testsuite/gcc.dg/pr47276.c +++ b/gcc/testsuite/gcc.dg/pr47276.c @@ -1,6 +1,11 @@ /* { dg-do compile } */ /* { dg-require-alias "" } */ /* { dg-require-visibility "" } */ + +#define ASMNAME(cname) ASMNAME2 (__USER_LABEL_PREFIX__, cname) +#define ASMNAME2(prefix, cname) STRING (prefix) cname +#define STRING(x) #x + extern void syslog (int __pri, __const char *__fmt, ...) __attribute__ ((__format__ (__printf__, 2, 3))); extern void vsyslog (int __pri, __const char *__fmt, int __ap) @@ -17,15 +22,15 @@ void __vsyslog_chk(int pri, int flag, const char *fmt, int ap) { } -extern __typeof (__vsyslog_chk) __EI___vsyslog_chk __asm__("" "__vsyslog_chk"); extern __typeof (__vsyslog_chk) __EI___vsyslog_chk __attribute__((alias ("" "__GI___vsyslog_chk"))); +extern __typeof (__vsyslog_chk) __EI___vsyslog_chk __asm__("" ASMNAME ("__vsyslog_chk")); extern __typeof (__vsyslog_chk) __EI___vsyslog_chk __attribute__((alias ("" "__GI___vsyslog_chk"))); void __syslog(int pri, const char *fmt, ...) { } extern __typeof (__syslog) syslog __attribute__ ((alias ("__syslog"))); -extern __typeof (syslog) __EI_syslog __asm__("" "syslog"); extern __typeof (syslog) __EI_syslog __attribute__((alias ("" "__GI_syslog"))); +extern __typeof (syslog) __EI_syslog __asm__("" ASMNAME ("syslog")); extern __typeof (syslog) __EI_syslog __attribute__((alias ("" "__GI_syslog"))); extern __typeof (__vsyslog) vsyslog __attribute__ ((alias ("__vsyslog"))); -extern __typeof (vsyslog) __EI_vsyslog __asm__("" "vsyslog"); extern __typeof (vsyslog) __EI_vsyslog __attribute__((alias ("" "__GI_vsyslog"))); -extern __typeof (syslog) syslog __asm__ ("" "__GI_syslog") __attribute__ ((visibility ("hidden"))); -extern __typeof (vsyslog) vsyslog __asm__ ("" "__GI_vsyslog") __attribute__ ((visibility ("hidden"))); -extern __typeof (__vsyslog_chk) __vsyslog_chk __asm__ ("" "__GI___vsyslog_chk") __attribute__ ((visibility ("hidden"))); +extern __typeof (vsyslog) __EI_vsyslog __asm__("" ASMNAME ("vsyslog")); extern __typeof (vsyslog) __EI_vsyslog __attribute__((alias ("" "__GI_vsyslog"))); +extern __typeof (syslog) syslog __asm__ ("" ASMNAME ("__GI_syslog")) __attribute__ ((visibility ("hidden"))); +extern __typeof (vsyslog) vsyslog __asm__ ("" ASMNAME ("__GI_vsyslog")) __attribute__ ((visibility ("hidden"))); +extern __typeof (__vsyslog_chk) __vsyslog_chk __asm__ ("" ASMNAME ("__GI___vsyslog_chk")) __attribute__ ((visibility ("hidden"))); diff --git a/gcc/testsuite/gcc.dg/pr50193-1.c b/gcc/testsuite/gcc.dg/pr50193-1.c new file mode 100644 index 00000000000..6abc9c40570 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr50193-1.c @@ -0,0 +1,10 @@ +/* PR 50193: ARM: ICE on a | (b << negative-constant) */ +/* Ensure that the compiler doesn't ICE. */ + +/* { dg-options "-O2" } */ + +int +foo(int a, int b) +{ + return a | (b << -3); /* { dg-warning "left shift count is negative" } */ +} diff --git a/gcc/testsuite/gcc.dg/pr50527.c b/gcc/testsuite/gcc.dg/pr50527.c new file mode 100644 index 00000000000..87fae9659d5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr50527.c @@ -0,0 +1,46 @@ +/* { dg-do run } */ +/* { dg-options "-Os --param large-stack-frame=30" } */ + +extern void abort (void); + +void __attribute__((noinline)) +bar (char *a) +{ +} + +void __attribute__((noinline)) +foo (char *a, int b) +{ +} + +void __attribute__((noinline)) +test_align (char *p, int aligned, unsigned int mask) +{ + int p_aligned = ((unsigned long int)p & mask) == 0; + if (aligned != p_aligned) + abort (); +} + +int +main () +{ + const int kIterations = 4; + char results[kIterations]; + int i; + unsigned int mask; + + mask = 0xf; + test_align (results, ((unsigned long int)results & mask) == 0, mask); + mask = 0x7; + test_align (results, ((unsigned long int)results & mask) == 0, mask); + mask = 0x3; + test_align (results, ((unsigned long int)results & mask) == 0, mask); + mask = 0x1; + test_align (results, ((unsigned long int)results & mask) == 0, mask); + + bar (results); + for (i = 0; i < kIterations; i++) + foo ("%d ", results[i]); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr48044.c b/gcc/testsuite/gcc.dg/torture/pr48044.c index fe3b73402cc..d20a634a119 100644 --- a/gcc/testsuite/gcc.dg/torture/pr48044.c +++ b/gcc/testsuite/gcc.dg/torture/pr48044.c @@ -2,6 +2,10 @@ /* { dg-do compile } */ /* { dg-require-alias "" } */ -int a __asm__ ("b") = 0; -extern int c __asm__ ("a") __attribute__ ((alias ("b"))); +#define ASMNAME(cname) ASMNAME2 (__USER_LABEL_PREFIX__, cname) +#define ASMNAME2(prefix, cname) STRING (prefix) cname +#define STRING(x) #x + +int a __asm__ (ASMNAME ("b")) = 0; +extern int c __asm__ (ASMNAME ("a")) __attribute__ ((alias ("b"))); extern int d __attribute__ ((weak, alias ("a"))); diff --git a/gcc/testsuite/gcc.dg/tree-ssa/restrict-4.c b/gcc/testsuite/gcc.dg/tree-ssa/restrict-4.c index a307c89f487..7bcdcdd053a 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/restrict-4.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/restrict-4.c @@ -22,5 +22,5 @@ bar (int *x, int y) return p1[y]; } -/* { dg-final { scan-tree-dump-times "return 1;" 2 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "return 1;" 2 "optimized" { xfail *-*-* } } } */ /* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-34.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-34.c new file mode 100644 index 00000000000..b0b54a22865 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-34.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-fre1-details" } */ + +#define vector __attribute__((vector_size(16) )) + +struct { + float i; + vector float global_res; +} s; +float foo(float f) +{ + vector float res = (vector float){0.0f,f,0.0f,1.0f}; + s.global_res = res; + return *((float*)&s.global_res + 1); +} + +/* { dg-final { scan-tree-dump "Replaced BIT_FIELD_REF.*with f" "fre1" } } */ +/* { dg-final { cleanup-tree-dump "fre1" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-35.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-35.c new file mode 100644 index 00000000000..dfbd7c1bb48 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-35.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-fre1-details" } */ + +struct s { _Complex float i; }; +void g(struct s *); + +float a1 (float dd) +{ + struct s sv; + sv.i = dd; + float d = __real__ sv.i; + g(&sv); + return d; +} + +/* { dg-final { scan-tree-dump "Replaced REALPART_EXPR.*with dd" "fre1" } } */ +/* { dg-final { cleanup-tree-dump "fre1" } } */ diff --git a/gcc/testsuite/gcc.dg/uninit-B.c b/gcc/testsuite/gcc.dg/uninit-B.c index f03dd701853..adb1461d951 100644 --- a/gcc/testsuite/gcc.dg/uninit-B.c +++ b/gcc/testsuite/gcc.dg/uninit-B.c @@ -9,7 +9,7 @@ void baz (void) { int i; - if (i) /* { dg-warning "is used uninitialized" "uninit i warning" { xfail *-*-* } } */ + if (i) /* { dg-warning "is used uninitialized" "uninit i warning" } */ bar (i); foo (&i); } diff --git a/gcc/testsuite/gcc.dg/uninit-pr19430.c b/gcc/testsuite/gcc.dg/uninit-pr19430.c index 4d2b4f62cef..36129314872 100644 --- a/gcc/testsuite/gcc.dg/uninit-pr19430.c +++ b/gcc/testsuite/gcc.dg/uninit-pr19430.c @@ -29,7 +29,7 @@ void frob(int *pi); int main(void) { int i; - printf("i = %d\n", i); /* { dg-warning "'i' is used uninitialized in this function" "" { xfail *-*-* } } */ + printf("i = %d\n", i); /* { dg-warning "'i' is used uninitialized in this function" "" } */ frob(&i); return 0; @@ -38,6 +38,6 @@ int main(void) void foo3(int*); void bar3(void) { int x; - if(x) /* { dg-warning "'x' is used uninitialized in this function" "uninitialized" { xfail *-*-* } } */ + if(x) /* { dg-warning "'x' is used uninitialized in this function" "uninitialized" } */ foo3(&x); } diff --git a/gcc/testsuite/gcc.dg/vect/pr50635.c b/gcc/testsuite/gcc.dg/vect/pr50635.c new file mode 100644 index 00000000000..6a7ac52e821 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr50635.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ + +typedef signed long int32_t; +typedef char int8_t; + +void f0a(int32_t * result, int32_t * arg1, int8_t * arg2, int32_t temp_3) +{ + int idx; + for (idx=0;idx<10;idx += 1) + { + int32_t temp_4; + int32_t temp_12; + + temp_4 = (-2 & arg2[idx]) + temp_3; + temp_12 = -2 * arg2[idx] + temp_4; + result[idx] = temp_12; + } +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-align-2.c b/gcc/testsuite/gcc.dg/vect/vect-align-2.c index 08a80112d73..293d07b241d 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-align-2.c +++ b/gcc/testsuite/gcc.dg/vect/vect-align-2.c @@ -15,7 +15,7 @@ struct foo { } __attribute__ ((packed)); struct foo f2; -int z[16] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; +int z[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}; __attribute__ ((noinline)) void fbar(struct foo *fp) diff --git a/gcc/testsuite/gcc.dg/vect/vect-cond-8.c b/gcc/testsuite/gcc.dg/vect/vect-cond-8.c new file mode 100644 index 00000000000..e5702c25a1d --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-cond-8.c @@ -0,0 +1,122 @@ +/* { dg-require-effective-target vect_cond_mixed } */ + +#include "tree-vect.h" + +#define N 1024 +float a[N], b[N], c[N]; +int d[N], e[N], f[N]; +unsigned char k[N]; + +__attribute__((noinline, noclone)) void +f1 (void) +{ + int i; + for (i = 0; i < N; ++i) + k[i] = a[i] < b[i] ? 17 : 0; +} + +__attribute__((noinline, noclone)) void +f2 (void) +{ + int i; + for (i = 0; i < N; ++i) + k[i] = a[i] < b[i] ? 0 : 24; +} + +__attribute__((noinline, noclone)) void +f3 (void) +{ + int i; + for (i = 0; i < N; ++i) + k[i] = a[i] < b[i] ? 51 : 12; +} + +__attribute__((noinline, noclone)) void +f4 (void) +{ + int i; + for (i = 0; i < N; ++i) + { + int d2 = d[i], e2 = e[i]; + f[i] = a[i] < b[i] ? d2 : e2; + } +} + +__attribute__((noinline, noclone)) void +f5 (void) +{ + int i; + for (i = 0; i < N; ++i) + { + float a2 = a[i], b2 = b[i]; + c[i] = d[i] < e[i] ? a2 : b2; + } +} + +int +main () +{ + int i; + + check_vect (); + + for (i = 0; i < N; i++) + { + switch (i % 9) + { + case 0: asm (""); a[i] = - i - 1; b[i] = i + 1; break; + case 1: a[i] = 0; b[i] = 0; break; + case 2: a[i] = i + 1; b[i] = - i - 1; break; + case 3: a[i] = i; b[i] = i + 7; break; + case 4: a[i] = i; b[i] = i; break; + case 5: a[i] = i + 16; b[i] = i + 3; break; + case 6: a[i] = - i - 5; b[i] = - i; break; + case 7: a[i] = - i; b[i] = - i; break; + case 8: a[i] = - i; b[i] = - i - 7; break; + } + d[i] = i; + e[i] = 2 * i; + } + f1 (); + for (i = 0; i < N; i++) + if (k[i] != ((i % 3) == 0 ? 17 : 0)) + abort (); + f2 (); + for (i = 0; i < N; i++) + if (k[i] != ((i % 3) == 0 ? 0 : 24)) + abort (); + f3 (); + for (i = 0; i < N; i++) + if (k[i] != ((i % 3) == 0 ? 51 : 12)) + abort (); + f4 (); + for (i = 0; i < N; i++) + if (f[i] != ((i % 3) == 0 ? d[i] : e[i])) + abort (); + for (i = 0; i < N; i++) + { + switch (i % 9) + { + case 0: asm (""); d[i] = - i - 1; e[i] = i + 1; break; + case 1: d[i] = 0; e[i] = 0; break; + case 2: d[i] = i + 1; e[i] = - i - 1; break; + case 3: d[i] = i; e[i] = i + 7; break; + case 4: d[i] = i; e[i] = i; break; + case 5: d[i] = i + 16; e[i] = i + 3; break; + case 6: d[i] = - i - 5; e[i] = - i; break; + case 7: d[i] = - i; e[i] = - i; break; + case 8: d[i] = - i; e[i] = - i - 7; break; + } + a[i] = i; + b[i] = i / 2; + } + f5 (); + for (i = 0; i < N; i++) + if (c[i] != ((i % 3) == 0 ? a[i] : b[i])) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "note: vectorized 1 loops" 5 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.target/arm/pr50305.c b/gcc/testsuite/gcc.target/arm/pr50305.c new file mode 100644 index 00000000000..2f6ad5cfeab --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/pr50305.c @@ -0,0 +1,60 @@ +/* { dg-do compile } */ +/* { dg-skip-if "incompatible options" { arm*-*-* } { "-march=*" } { "-march=armv7-a" } } */ +/* { dg-options "-O2 -fno-omit-frame-pointer -marm -march=armv7-a -mfpu=vfp3" } */ + +struct event { + unsigned long long id; + unsigned int flag; +}; + +void dummy(void) +{ + /* This is here to ensure that the offset of perf_event_id below + relative to the LANCHOR symbol exceeds the allowed displacement. */ + static int __warned[300]; + __warned[0] = 1; +} + +extern void *kmem_cache_alloc_trace (void *cachep); +extern void *cs_cachep; +extern int nr_cpu_ids; + +struct event * +event_alloc (int cpu) +{ + static unsigned long long __attribute__((aligned(8))) perf_event_id; + struct event *event; + unsigned long long result; + unsigned long tmp; + + if (cpu >= nr_cpu_ids) + return 0; + + event = kmem_cache_alloc_trace (cs_cachep); + + __asm__ __volatile__ ("dmb" : : : "memory"); + + __asm__ __volatile__("@ atomic64_add_return\n" +"1: ldrexd %0, %H0, [%3]\n" +" adds %0, %0, %4\n" +" adc %H0, %H0, %H4\n" +" strexd %1, %0, %H0, [%3]\n" +" teq %1, #0\n" +" bne 1b" + : "=&r" (result), "=&r" (tmp), "+Qo" (perf_event_id) + : "r" (&perf_event_id), "r" (1LL) + : "cc"); + + __asm__ __volatile__ ("dmb" : : : "memory"); + + event->id = result; + + if (cpu) + event->flag = 1; + + for (cpu = 0; cpu < nr_cpu_ids; cpu++) + kmem_cache_alloc_trace (cs_cachep); + + return event; +} + diff --git a/gcc/testsuite/gcc.target/arm/shiftable.c b/gcc/testsuite/gcc.target/arm/shiftable.c new file mode 100644 index 00000000000..f3080620a9e --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/shiftable.c @@ -0,0 +1,63 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-require-effective-target arm32 } */ + +/* ARM has shift-and-alu insns. Depending on the ALU op GCC represents some + of these as a left shift, others as a multiply. Check that we match the + right one. */ + +int +plus (int a, int b) +{ + return (a * 64) + b; +} + +/* { dg-final { scan-assembler "add.*\[al]sl #6" } } */ + +int +minus (int a, int b) +{ + return a - (b * 64); +} + +/* { dg-final { scan-assembler "sub.*\[al]sl #6" } } */ + +int +ior (int a, int b) +{ + return (a * 64) | b; +} + +/* { dg-final { scan-assembler "orr.*\[al]sl #6" } } */ + +int +xor (int a, int b) +{ + return (a * 64) ^ b; +} + +/* { dg-final { scan-assembler "eor.*\[al]sl #6" } } */ + +int +and (int a, int b) +{ + return (a * 64) & b; +} + +/* { dg-final { scan-assembler "and.*\[al]sl #6" } } */ + +int +rsb (int a, int b) +{ + return (a * 64) - b; +} + +/* { dg-final { scan-assembler "rsb.*\[al]sl #6" } } */ + +int +mvn (int a, int b) +{ + return ~(a * 64); +} + +/* { dg-final { scan-assembler "mvn.*\[al]sl #6" } } */ diff --git a/gcc/testsuite/gcc.target/i386/avx256-unaligned-load-2.c b/gcc/testsuite/gcc.target/i386/avx256-unaligned-load-2.c index 7d188e2b466..f1d79793ff8 100644 --- a/gcc/testsuite/gcc.target/i386/avx256-unaligned-load-2.c +++ b/gcc/testsuite/gcc.target/i386/avx256-unaligned-load-2.c @@ -26,4 +26,4 @@ avx_test (void) /* { dg-final { scan-assembler-not "\\*avx_movdqu256/1" } } */ /* { dg-final { scan-assembler "\\*sse2_movdqu/1" } } */ -/* { dg-final { scan-assembler "vinsertf128" } } */ +/* { dg-final { scan-assembler "vinsert.128" } } */ diff --git a/gcc/testsuite/gcc.target/i386/avx256-unaligned-store-2.c b/gcc/testsuite/gcc.target/i386/avx256-unaligned-store-2.c index d8ae5a90189..3339cc5e703 100644 --- a/gcc/testsuite/gcc.target/i386/avx256-unaligned-store-2.c +++ b/gcc/testsuite/gcc.target/i386/avx256-unaligned-store-2.c @@ -26,4 +26,4 @@ avx_test (void) /* { dg-final { scan-assembler-not "\\*avx_movdqu256/2" } } */ /* { dg-final { scan-assembler "vmovdqu.*\\*movv16qi_internal/3" } } */ -/* { dg-final { scan-assembler "vextractf128" } } */ +/* { dg-final { scan-assembler "vextract.128" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr50603.c b/gcc/testsuite/gcc.target/i386/pr50603.c new file mode 100644 index 00000000000..101ef85484d --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr50603.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +extern int *foo; + +int +bar (int x) +{ + return foo[x]; +} +/* { dg-final { scan-assembler-not "lea\[lq\]" } } */ diff --git a/gcc/testsuite/gcc.target/sparc/cmask.c b/gcc/testsuite/gcc.target/sparc/cmask.c index b3168ec321d..989274c6858 100644 --- a/gcc/testsuite/gcc.target/sparc/cmask.c +++ b/gcc/testsuite/gcc.target/sparc/cmask.c @@ -1,4 +1,4 @@ -/* { dg-do compile } */ +/* { dg-do compile { target { vis3 } } } */ /* { dg-options "-mcpu=niagara3 -mvis" } */ void test_cm8 (long x) diff --git a/gcc/testsuite/gcc.target/sparc/fhalve.c b/gcc/testsuite/gcc.target/sparc/fhalve.c index 340b936b8fa..737fc71bbcf 100644 --- a/gcc/testsuite/gcc.target/sparc/fhalve.c +++ b/gcc/testsuite/gcc.target/sparc/fhalve.c @@ -1,4 +1,4 @@ -/* { dg-do compile } */ +/* { dg-do compile { target { vis3 } } } */ /* { dg-options "-mcpu=niagara3 -mvis" } */ float test_fhadds (float x, float y) diff --git a/gcc/testsuite/gcc.target/sparc/fnegop.c b/gcc/testsuite/gcc.target/sparc/fnegop.c index 25f8c199e24..3e3e72c820c 100644 --- a/gcc/testsuite/gcc.target/sparc/fnegop.c +++ b/gcc/testsuite/gcc.target/sparc/fnegop.c @@ -1,4 +1,4 @@ -/* { dg-do compile } */ +/* { dg-do compile { target { vis3 } } } */ /* { dg-options "-O2 -mcpu=niagara3 -mvis" } */ float test_fnadds(float x, float y) diff --git a/gcc/testsuite/gcc.target/sparc/fpadds.c b/gcc/testsuite/gcc.target/sparc/fpadds.c index d0704e03eda..f55cb057a2a 100644 --- a/gcc/testsuite/gcc.target/sparc/fpadds.c +++ b/gcc/testsuite/gcc.target/sparc/fpadds.c @@ -1,4 +1,4 @@ -/* { dg-do compile } */ +/* { dg-do compile { target { vis3 } } } */ /* { dg-options "-mcpu=niagara3 -mvis" } */ typedef int __v2si __attribute__((vector_size(8))); typedef int __v1si __attribute__((vector_size(4))); diff --git a/gcc/testsuite/gcc.target/sparc/fshift.c b/gcc/testsuite/gcc.target/sparc/fshift.c index a12df0451cb..6adbed69171 100644 --- a/gcc/testsuite/gcc.target/sparc/fshift.c +++ b/gcc/testsuite/gcc.target/sparc/fshift.c @@ -1,4 +1,4 @@ -/* { dg-do compile } */ +/* { dg-do compile { target { vis3 } } } */ /* { dg-options "-mcpu=niagara3 -mvis" } */ typedef int __v2si __attribute__((vector_size(8))); typedef short __v4hi __attribute__((vector_size(8))); diff --git a/gcc/testsuite/gcc.target/sparc/fucmp.c b/gcc/testsuite/gcc.target/sparc/fucmp.c index 7f291c3e7ed..4e7ecadcd4a 100644 --- a/gcc/testsuite/gcc.target/sparc/fucmp.c +++ b/gcc/testsuite/gcc.target/sparc/fucmp.c @@ -1,4 +1,4 @@ -/* { dg-do compile } */ +/* { dg-do compile { target { vis3 } } } */ /* { dg-options "-mcpu=niagara3 -mvis" } */ typedef unsigned char vec8 __attribute__((vector_size(8))); diff --git a/gcc/testsuite/gcc.target/sparc/lzd.c b/gcc/testsuite/gcc.target/sparc/lzd.c index a8978296300..5ffaf56e558 100644 --- a/gcc/testsuite/gcc.target/sparc/lzd.c +++ b/gcc/testsuite/gcc.target/sparc/lzd.c @@ -1,4 +1,4 @@ -/* { dg-do compile } */ +/* { dg-do compile { target { vis3 } } } */ /* { dg-options "-mcpu=niagara3" } */ int test_clz(int a) { diff --git a/gcc/testsuite/gcc.target/sparc/sparc.exp b/gcc/testsuite/gcc.target/sparc/sparc.exp index 9658d08bc9c..51c9c16ecb7 100644 --- a/gcc/testsuite/gcc.target/sparc/sparc.exp +++ b/gcc/testsuite/gcc.target/sparc/sparc.exp @@ -24,6 +24,17 @@ if ![istarget sparc*-*-*] then { # Load support procs. load_lib gcc-dg.exp +# Return 1 if vis3 instructions can be compiled. +proc check_effective_target_vis3 { } { + return [check_no_compiler_messages vis3 object { + long long + _vis3_fpadd64 (long long __X, long long __Y) + { + return __builtin_vis_fpadd64 (__X, __Y); + } + } "-mcpu=niagara3 -mvis" ] +} + # If a testcase doesn't have special options, use these. global DEFAULT_CFLAGS if ![info exists DEFAULT_CFLAGS] then { diff --git a/gcc/testsuite/gcc.target/sparc/vis3misc.c b/gcc/testsuite/gcc.target/sparc/vis3misc.c index 8a9535e8fb5..e3ef49e210d 100644 --- a/gcc/testsuite/gcc.target/sparc/vis3misc.c +++ b/gcc/testsuite/gcc.target/sparc/vis3misc.c @@ -1,4 +1,4 @@ -/* { dg-do compile } */ +/* { dg-do compile { target { vis3 } } } */ /* { dg-options "-mcpu=niagara3 -mvis" } */ typedef int __v2si __attribute__((vector_size(8))); typedef short __v4hi __attribute__((vector_size(8))); diff --git a/gcc/testsuite/gcc.target/sparc/xmul.c b/gcc/testsuite/gcc.target/sparc/xmul.c index ce80e6cbbe0..5d249d092db 100644 --- a/gcc/testsuite/gcc.target/sparc/xmul.c +++ b/gcc/testsuite/gcc.target/sparc/xmul.c @@ -1,4 +1,4 @@ -/* { dg-do compile } */ +/* { dg-do compile { target { vis3 } } } */ /* { dg-options "-mcpu=niagara3 -mvis" } */ typedef long long int64_t; diff --git a/gcc/testsuite/gfortran.dg/c_sizeof_2.f90 b/gcc/testsuite/gfortran.dg/c_sizeof_2.f90 index e163797470f..e3911facf6a 100644 --- a/gcc/testsuite/gfortran.dg/c_sizeof_2.f90 +++ b/gcc/testsuite/gfortran.dg/c_sizeof_2.f90 @@ -2,7 +2,7 @@ ! { dg-options "-std=f2003 -Wall -Wno-conversion" } ! Support F2008's c_sizeof() ! -USE ISO_C_BINDING, only: C_SIZE_T, c_sizeof ! { dg-error "new in Fortran 2008" } +USE ISO_C_BINDING, only: C_SIZE_T, c_sizeof ! { dg-error "is not in the selected standard" } integer(C_SIZE_T) :: i i = c_sizeof(i) end diff --git a/gcc/testsuite/gfortran.dg/class_46.f03 b/gcc/testsuite/gfortran.dg/class_46.f03 new file mode 100644 index 00000000000..4719c252f63 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/class_46.f03 @@ -0,0 +1,18 @@ +! { dg-do run } +! +! PR 50625: [4.6/4.7 Regression][OOP] ALLOCATABLE attribute lost for module CLASS variables +! +! Contributed by Tobias Burnus <burnus@gcc.gnu.org> + +module m +type t +end type t +class(t), allocatable :: x +end module m + +use m +implicit none +if (allocated(x)) call abort() +end + +! { dg-final { cleanup-modules "m" } } diff --git a/gcc/testsuite/gfortran.dg/common_14.f90 b/gcc/testsuite/gfortran.dg/common_14.f90 index aced168c655..892e4a5705f 100644 --- a/gcc/testsuite/gfortran.dg/common_14.f90 +++ b/gcc/testsuite/gfortran.dg/common_14.f90 @@ -1,4 +1,5 @@ ! { dg-do compile } +! { dg-options "-Wno-align-commons" } ! ! PR fortran/45044 ! diff --git a/gcc/testsuite/gfortran.dg/common_16.f90 b/gcc/testsuite/gfortran.dg/common_16.f90 new file mode 100644 index 00000000000..3314e80ef9d --- /dev/null +++ b/gcc/testsuite/gfortran.dg/common_16.f90 @@ -0,0 +1,12 @@ +! { dg-do compile } +! { dg-options "-pedantic -mdalign" { target sh*-*-* } } +! +! PR fortran/50273 +! +subroutine test() + character :: a + integer :: b + character :: c + common /global_var/ a, b, c ! { dg-warning "Padding of 3 bytes required before 'b' in COMMON" } + print *, a, b, c +end subroutine test diff --git a/gcc/testsuite/gfortran.dg/iso_c_binding_param_1.f90 b/gcc/testsuite/gfortran.dg/iso_c_binding_param_1.f90 new file mode 100644 index 00000000000..dae9cc3703f --- /dev/null +++ b/gcc/testsuite/gfortran.dg/iso_c_binding_param_1.f90 @@ -0,0 +1,12 @@ +! { dg-do compile } +! { dg-options "-std=f2008" } +! +! Check that the GNU additions to ISO_C_Binding are properly diagnosed +! +use, intrinsic :: iso_c_binding, only: c_int128_t ! { dg-error "is not in the selected standard" } +use, intrinsic :: iso_c_binding, only: c_int_least128_t ! { dg-error "is not in the selected standard" } +use, intrinsic :: iso_c_binding, only: c_int_fast128_t ! { dg-error "is not in the selected standard" } +use, intrinsic :: iso_c_binding, only: c_float128 ! { dg-error "is not in the selected standard" } +use, intrinsic :: iso_c_binding, only: c_float128_complex ! { dg-error "is not in the selected standard" } +implicit none +end diff --git a/gcc/testsuite/gfortran.dg/iso_c_binding_param_2.f90 b/gcc/testsuite/gfortran.dg/iso_c_binding_param_2.f90 new file mode 100644 index 00000000000..7b78743452a --- /dev/null +++ b/gcc/testsuite/gfortran.dg/iso_c_binding_param_2.f90 @@ -0,0 +1,20 @@ +! { dg-do compile } +! { dg-options "-O -fdump-tree-optimized" } +! +! Check that the GNU additions to ISO_C_Binding are accepted +! +use, intrinsic :: iso_c_binding, only: c_int128_t +use, intrinsic :: iso_c_binding, only: c_int_least128_t +use, intrinsic :: iso_c_binding, only: c_int_fast128_t +use, intrinsic :: iso_c_binding, only: c_float128 +use, intrinsic :: iso_c_binding, only: c_float128_complex +implicit none +if (c_int128_t >= 0 .and. c_int128_t /= 16) call unreachable() +if (c_int_least128_t >= 0 .and. c_int_least128_t < 16) call unreachable() +if (c_int_fast128_t >= 0 .and. c_int_fast128_t < 16) call unreachable() +if (c_float128 >= 0 .and. c_float128 /= 16) call unreachable() +if (c_float128_complex >= 0 .and. c_float128_complex /= 16) call unreachable() +end + +! { dg-final { scan-tree-dump-times "unreachable" 0 "optimized" } } +! { dg-final { cleanup-tree-dump "optimized" } } diff --git a/gcc/testsuite/gfortran.dg/pointer_function_result_1.f90 b/gcc/testsuite/gfortran.dg/pointer_function_result_1.f90 new file mode 100644 index 00000000000..764a666be96 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pointer_function_result_1.f90 @@ -0,0 +1,28 @@ +! { dg-do run } +! Test the fix for PR47844, in which the stride in the function result +! was ignored. Previously, the result was [1,3] at lines 15 and 16. +! +! Contributed by KePu <Kdx1999@gmail.com> +! +PROGRAM test_pointer_value + IMPLICIT NONE + INTEGER, DIMENSION(10), TARGET :: array= [1,3,5,7,9,11,13,15,17,19] + INTEGER, dimension(2) :: array_fifth + INTEGER, POINTER, DIMENSION(:) :: ptr_array => NULL() + INTEGER, POINTER, DIMENSION(:) :: ptr_array_fifth => NULL() + ptr_array => array + array_fifth = every_fifth (ptr_array) + if (any (array_fifth .ne. [1,11])) call abort + if (any (every_fifth(ptr_array) .ne. [1,11])) call abort +CONTAINS + FUNCTION every_fifth (ptr_array) RESULT (ptr_fifth) + IMPLICIT NONE + INTEGER, POINTER, DIMENSION(:) :: ptr_fifth + INTEGER, POINTER, DIMENSION(:), INTENT(in) :: ptr_array + INTEGER :: low + INTEGER :: high + low = LBOUND (ptr_array, 1) + high = UBOUND (ptr_array, 1) + ptr_fifth => ptr_array (low: high: 5) + END FUNCTION every_fifth +END PROGRAM test_pointer_value diff --git a/gcc/testsuite/gfortran.dg/proc_decl_27.f90 b/gcc/testsuite/gfortran.dg/proc_decl_27.f90 new file mode 100644 index 00000000000..30ff4def30d --- /dev/null +++ b/gcc/testsuite/gfortran.dg/proc_decl_27.f90 @@ -0,0 +1,25 @@ +! { dg-do compile } +! +! PR 50659: [4.5/4.6/4.7 Regression] [F03] ICE on invalid with procedure interface +! +! Contributed by Andrew Benson <abenson@caltech.edu> + +module m1 + integer :: arrSize +end module + +module m2 +contains + function Proc (arg) + use m1 + double precision, dimension(arrSize) :: proc + double precision :: arg + end function +end + + use m2 + implicit none + procedure(Proc) :: Proc_Get +end + +! { dg-final { cleanup-modules "m1 m2" } } diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index 5d236f78312..550d5345244 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -3234,6 +3234,26 @@ proc check_effective_target_vect_condition { } { return $et_vect_cond_saved } +# Return 1 if the target supports vector conditional operations where +# the comparison has different type from the lhs, 0 otherwise. + +proc check_effective_target_vect_cond_mixed { } { + global et_vect_cond_mixed_saved + + if [info exists et_vect_cond_mixed_saved] { + verbose "check_effective_target_vect_cond_mixed: using cached result" 2 + } else { + set et_vect_cond_mixed_saved 0 + if { [istarget i?86-*-*] + || [istarget x86_64-*-*] } { + set et_vect_cond_mixed_saved 1 + } + } + + verbose "check_effective_target_vect_cond_mixed: returning $et_vect_cond_mixed_saved" 2 + return $et_vect_cond_mixed_saved +} + # Return 1 if the target supports vector char multiplication, 0 otherwise. proc check_effective_target_vect_char_mult { } { diff --git a/gcc/testsuite/objc/execute/initialize-1.m b/gcc/testsuite/objc/execute/initialize-1.m new file mode 100644 index 00000000000..9ca4aebbe69 --- /dev/null +++ b/gcc/testsuite/objc/execute/initialize-1.m @@ -0,0 +1,47 @@ +/* Contributed by Nicola Pero - Sat 8 Oct 2011 16:47:48 BST */ +#include <objc/objc.h> + +/* Test that if a class has no +initialize method, the superclass + implementation is called. */ + +static int class_variable = 0; + +@interface TestClass +{ + Class isa; +} ++ (void) initialize; ++ (int) classVariable; +@end + +@implementation TestClass ++ (void) initialize +{ + class_variable++; +} ++ (int) classVariable +{ + return class_variable; +} +@end + +@interface TestSubClass : TestClass +@end + +@implementation TestSubClass +@end + +int main (void) +{ + if ([TestClass classVariable] != 1) + { + abort (); + } + + if ([TestSubClass classVariable] != 2) + { + abort (); + } + + return 0; +} diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index 598ef2ac7a6..bcf71b99bbb 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -3727,11 +3727,11 @@ verify_gimple_assign_ternary (gimple stmt) } break; - case VEC_SHUFFLE_EXPR: + case VEC_PERM_EXPR: if (!useless_type_conversion_p (lhs_type, rhs1_type) || !useless_type_conversion_p (lhs_type, rhs2_type)) { - error ("type mismatch in vector shuffle expression"); + error ("type mismatch in vector permute expression"); debug_generic_expr (lhs_type); debug_generic_expr (rhs1_type); debug_generic_expr (rhs2_type); @@ -3743,7 +3743,7 @@ verify_gimple_assign_ternary (gimple stmt) || TREE_CODE (rhs2_type) != VECTOR_TYPE || TREE_CODE (rhs3_type) != VECTOR_TYPE) { - error ("vector types expected in vector shuffle expression"); + error ("vector types expected in vector permute expression"); debug_generic_expr (lhs_type); debug_generic_expr (rhs1_type); debug_generic_expr (rhs2_type); @@ -3758,7 +3758,7 @@ verify_gimple_assign_ternary (gimple stmt) != TYPE_VECTOR_SUBPARTS (lhs_type)) { error ("vectors with different element number found " - "in vector shuffle expression"); + "in vector permute expression"); debug_generic_expr (lhs_type); debug_generic_expr (rhs1_type); debug_generic_expr (rhs2_type); @@ -3770,7 +3770,7 @@ verify_gimple_assign_ternary (gimple stmt) || GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (rhs3_type))) != GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (rhs1_type)))) { - error ("invalid mask type in vector shuffle expression"); + error ("invalid mask type in vector permute expression"); debug_generic_expr (lhs_type); debug_generic_expr (rhs1_type); debug_generic_expr (rhs2_type); diff --git a/gcc/tree-dfa.c b/gcc/tree-dfa.c index 62d4bfe3fb8..0ecec816b6a 100644 --- a/gcc/tree-dfa.c +++ b/gcc/tree-dfa.c @@ -580,8 +580,9 @@ set_default_def (tree var, tree def) bool add_referenced_var (tree var) { - get_var_ann (var); gcc_assert (DECL_P (var)); + if (!*DECL_VAR_ANN_PTR (var)) + create_var_ann (var); /* Insert VAR into the referenced_vars hash table if it isn't present. */ if (referenced_var_check_and_insert (var)) diff --git a/gcc/tree-flow-inline.h b/gcc/tree-flow-inline.h index b9c5e16e972..56edae9fef3 100644 --- a/gcc/tree-flow-inline.h +++ b/gcc/tree-flow-inline.h @@ -145,16 +145,6 @@ var_ann (const_tree t) return p ? *p : NULL; } -/* Return the variable annotation for T, which must be a _DECL node. - Create the variable annotation if it doesn't exist. */ -static inline var_ann_t -get_var_ann (tree var) -{ - var_ann_t *p = DECL_VAR_ANN_PTR (var); - gcc_checking_assert (p); - return *p ? *p : create_var_ann (var); -} - /* Get the number of the next statement uid to be allocated. */ static inline unsigned int gimple_stmt_max_uid (struct function *fn) @@ -568,7 +558,7 @@ phi_arg_index_from_use (use_operand_p use) static inline void set_is_used (tree var) { - var_ann_t ann = get_var_ann (var); + var_ann_t ann = var_ann (var); ann->used = true; } diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h index d4bf54cbe69..1152b7d0de4 100644 --- a/gcc/tree-flow.h +++ b/gcc/tree-flow.h @@ -278,7 +278,6 @@ typedef struct immediate_use_iterator_d typedef struct var_ann_d *var_ann_t; static inline var_ann_t var_ann (const_tree); -static inline var_ann_t get_var_ann (tree); static inline void update_stmt (gimple); static inline int get_lineno (const_gimple); diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 8c60f4d73a9..e2f76e1c608 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -3285,7 +3285,7 @@ estimate_operator_cost (enum tree_code code, eni_weights *weights, ??? We may consider mapping RTL costs to this. */ case COND_EXPR: case VEC_COND_EXPR: - case VEC_SHUFFLE_EXPR: + case VEC_PERM_EXPR: case PLUS_EXPR: case POINTER_PLUS_EXPR: diff --git a/gcc/tree-mudflap.c b/gcc/tree-mudflap.c index f9b45994917..9479aebfb34 100644 --- a/gcc/tree-mudflap.c +++ b/gcc/tree-mudflap.c @@ -418,6 +418,10 @@ execute_mudflap_function_ops (void) push_gimplify_context (&gctx); + add_referenced_var (mf_cache_array_decl); + add_referenced_var (mf_cache_shift_decl); + add_referenced_var (mf_cache_mask_decl); + /* In multithreaded mode, don't cache the lookup cache parameters. */ if (! flag_mudflap_threads) mf_decl_cache_locals (); @@ -969,7 +973,9 @@ mf_xform_statements (void) case GIMPLE_CALL: { tree fndecl = gimple_call_fndecl (s); - if (fndecl && (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_ALLOCA)) + if (fndecl && (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_ALLOCA + || (DECL_FUNCTION_CODE (fndecl) + == BUILT_IN_ALLOCA_WITH_ALIGN))) gimple_call_set_cannot_inline (s, true); } break; diff --git a/gcc/tree-object-size.c b/gcc/tree-object-size.c index 851bba914fa..2998fb59da0 100644 --- a/gcc/tree-object-size.c +++ b/gcc/tree-object-size.c @@ -411,6 +411,7 @@ alloc_object_size (const_gimple call, int object_size_type) /* fall through */ case BUILT_IN_MALLOC: case BUILT_IN_ALLOCA: + case BUILT_IN_ALLOCA_WITH_ALIGN: arg1 = 0; default: break; diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c index c61e901d8be..8acabb16e16 100644 --- a/gcc/tree-pretty-print.c +++ b/gcc/tree-pretty-print.c @@ -2070,8 +2070,8 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags, pp_string (buffer, " > "); break; - case VEC_SHUFFLE_EXPR: - pp_string (buffer, " VEC_SHUFFLE_EXPR < "); + case VEC_PERM_EXPR: + pp_string (buffer, " VEC_PERM_EXPR < "); dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false); pp_string (buffer, " , "); dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false); diff --git a/gcc/tree-profile.c b/gcc/tree-profile.c index 98f7d678792..c56650c066e 100644 --- a/gcc/tree-profile.c +++ b/gcc/tree-profile.c @@ -224,6 +224,7 @@ gimple_gen_edge_profiler (int edgeno, edge e) one = build_int_cst (gcov_type_node, 1); stmt1 = gimple_build_assign (gcov_type_tmp_var, ref); gimple_assign_set_lhs (stmt1, make_ssa_name (gcov_type_tmp_var, stmt1)); + find_referenced_vars_in (stmt1); stmt2 = gimple_build_assign_with_ops (PLUS_EXPR, gcov_type_tmp_var, gimple_assign_lhs (stmt1), one); gimple_assign_set_lhs (stmt2, make_ssa_name (gcov_type_tmp_var, stmt2)); @@ -270,6 +271,7 @@ gimple_gen_interval_profiler (histogram_value value, unsigned tag, unsigned base val = prepare_instrumented_value (&gsi, value); call = gimple_build_call (tree_interval_profiler_fn, 4, ref_ptr, val, start, steps); + find_referenced_vars_in (call); gsi_insert_before (&gsi, call, GSI_NEW_STMT); } @@ -290,6 +292,7 @@ gimple_gen_pow2_profiler (histogram_value value, unsigned tag, unsigned base) true, NULL_TREE, true, GSI_SAME_STMT); val = prepare_instrumented_value (&gsi, value); call = gimple_build_call (tree_pow2_profiler_fn, 2, ref_ptr, val); + find_referenced_vars_in (call); gsi_insert_before (&gsi, call, GSI_NEW_STMT); } @@ -310,6 +313,7 @@ gimple_gen_one_value_profiler (histogram_value value, unsigned tag, unsigned bas true, NULL_TREE, true, GSI_SAME_STMT); val = prepare_instrumented_value (&gsi, value); call = gimple_build_call (tree_one_value_profiler_fn, 2, ref_ptr, val); + find_referenced_vars_in (call); gsi_insert_before (&gsi, call, GSI_NEW_STMT); } @@ -340,9 +344,12 @@ gimple_gen_ic_profiler (histogram_value value, unsigned tag, unsigned base) tmp1 = create_tmp_reg (ptr_void, "PROF"); stmt1 = gimple_build_assign (ic_gcov_type_ptr_var, ref_ptr); + find_referenced_vars_in (stmt1); stmt2 = gimple_build_assign (tmp1, unshare_expr (value->hvalue.value)); gimple_assign_set_lhs (stmt2, make_ssa_name (tmp1, stmt2)); + find_referenced_vars_in (stmt2); stmt3 = gimple_build_assign (ic_void_ptr_var, gimple_assign_lhs (stmt2)); + add_referenced_var (ic_void_ptr_var); gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT); gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT); @@ -378,9 +385,11 @@ gimple_gen_ic_func_profiler (void) counter_ptr = force_gimple_operand_gsi (&gsi, ic_gcov_type_ptr_var, true, NULL_TREE, true, GSI_SAME_STMT); + add_referenced_var (ic_gcov_type_ptr_var); ptr_var = force_gimple_operand_gsi (&gsi, ic_void_ptr_var, true, NULL_TREE, true, GSI_SAME_STMT); + add_referenced_var (ic_void_ptr_var); tree_uid = build_int_cst (gcov_type_node, current_function_funcdef_no); stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 4, counter_ptr, tree_uid, cur_func, ptr_var); @@ -429,6 +438,7 @@ gimple_gen_average_profiler (histogram_value value, unsigned tag, unsigned base) true, GSI_SAME_STMT); val = prepare_instrumented_value (&gsi, value); call = gimple_build_call (tree_average_profiler_fn, 2, ref_ptr, val); + find_referenced_vars_in (call); gsi_insert_before (&gsi, call, GSI_NEW_STMT); } @@ -449,6 +459,7 @@ gimple_gen_ior_profiler (histogram_value value, unsigned tag, unsigned base) true, NULL_TREE, true, GSI_SAME_STMT); val = prepare_instrumented_value (&gsi, value); call = gimple_build_call (tree_ior_profiler_fn, 2, ref_ptr, val); + find_referenced_vars_in (call); gsi_insert_before (&gsi, call, GSI_NEW_STMT); } diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c index a89094467f1..506e778ee06 100644 --- a/gcc/tree-ssa-alias.c +++ b/gcc/tree-ssa-alias.c @@ -1260,6 +1260,7 @@ ref_maybe_used_by_call_p_1 (gimple call, ao_ref *ref) case BUILT_IN_MALLOC: case BUILT_IN_CALLOC: case BUILT_IN_ALLOCA: + case BUILT_IN_ALLOCA_WITH_ALIGN: case BUILT_IN_STACK_SAVE: case BUILT_IN_STACK_RESTORE: case BUILT_IN_MEMSET: @@ -1554,6 +1555,7 @@ call_may_clobber_ref_p_1 (gimple call, ao_ref *ref) return false; case BUILT_IN_STACK_SAVE: case BUILT_IN_ALLOCA: + case BUILT_IN_ALLOCA_WITH_ALIGN: case BUILT_IN_ASSUME_ALIGNED: return false; /* Freeing memory kills the pointed-to memory. More importantly diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c index b5774040e32..e207e232e01 100644 --- a/gcc/tree-ssa-ccp.c +++ b/gcc/tree-ssa-ccp.c @@ -1492,6 +1492,7 @@ evaluate_stmt (gimple stmt) tree simplified = NULL_TREE; ccp_lattice_t likelyvalue = likely_value (stmt); bool is_constant = false; + unsigned int align; if (dump_file && (dump_flags & TDF_DETAILS)) { @@ -1632,10 +1633,14 @@ evaluate_stmt (gimple stmt) break; case BUILT_IN_ALLOCA: + case BUILT_IN_ALLOCA_WITH_ALIGN: + align = (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_ALLOCA_WITH_ALIGN + ? TREE_INT_CST_LOW (gimple_call_arg (stmt, 1)) + : BIGGEST_ALIGNMENT); val.lattice_val = CONSTANT; val.value = build_int_cst (TREE_TYPE (gimple_get_lhs (stmt)), 0); val.mask = shwi_to_double_int - (~(((HOST_WIDE_INT) BIGGEST_ALIGNMENT) + (~(((HOST_WIDE_INT) align) / BITS_PER_UNIT - 1)); break; @@ -1685,15 +1690,15 @@ evaluate_stmt (gimple stmt) return val; } -/* Detects a vla-related alloca with a constant argument. Declares fixed-size - array and return the address, if found, otherwise returns NULL_TREE. */ +/* Detects a __builtin_alloca_with_align with constant size argument. Declares + fixed-size array and returns the address, if found, otherwise returns + NULL_TREE. */ static tree -fold_builtin_alloca_for_var (gimple stmt) +fold_builtin_alloca_with_align (gimple stmt) { unsigned HOST_WIDE_INT size, threshold, n_elem; tree lhs, arg, block, var, elem_type, array_type; - unsigned int align; /* Get lhs. */ lhs = gimple_call_lhs (stmt); @@ -1709,10 +1714,10 @@ fold_builtin_alloca_for_var (gimple stmt) size = TREE_INT_CST_LOW (arg); - /* Heuristic: don't fold large vlas. */ + /* Heuristic: don't fold large allocas. */ threshold = (unsigned HOST_WIDE_INT)PARAM_VALUE (PARAM_LARGE_STACK_FRAME); - /* In case a vla is declared at function scope, it has the same lifetime as a - declared array, so we allow a larger size. */ + /* In case the alloca is located at function entry, it has the same lifetime + as a declared array, so we allow a larger size. */ block = gimple_block (stmt); if (!(cfun->after_inlining && TREE_CODE (BLOCK_SUPERCONTEXT (block)) == FUNCTION_DECL)) @@ -1723,12 +1728,9 @@ fold_builtin_alloca_for_var (gimple stmt) /* Declare array. */ elem_type = build_nonstandard_integer_type (BITS_PER_UNIT, 1); n_elem = size * 8 / BITS_PER_UNIT; - align = MIN (size * 8, BIGGEST_ALIGNMENT); - if (align < BITS_PER_UNIT) - align = BITS_PER_UNIT; array_type = build_array_type_nelts (elem_type, n_elem); var = create_tmp_var (array_type, NULL); - DECL_ALIGN (var) = align; + DECL_ALIGN (var) = TREE_INT_CST_LOW (gimple_call_arg (stmt, 1)); { struct ptr_info_def *pi = SSA_NAME_PTR_INFO (lhs); if (pi != NULL && !pi->pt.anything) @@ -1813,12 +1815,12 @@ ccp_fold_stmt (gimple_stmt_iterator *gsi) if (gimple_call_internal_p (stmt)) return false; - /* The heuristic of fold_builtin_alloca_for_var differs before and after - inlining, so we don't require the arg to be changed into a constant - for folding, but just to be constant. */ - if (gimple_call_alloca_for_var_p (stmt)) + /* The heuristic of fold_builtin_alloca_with_align differs before and + after inlining, so we don't require the arg to be changed into a + constant for folding, but just to be constant. */ + if (gimple_call_builtin_p (stmt, BUILT_IN_ALLOCA_WITH_ALIGN)) { - tree new_rhs = fold_builtin_alloca_for_var (stmt); + tree new_rhs = fold_builtin_alloca_with_align (stmt); if (new_rhs) { bool res = update_call_from_tree (gsi, new_rhs); @@ -2093,7 +2095,8 @@ optimize_stack_restore (gimple_stmt_iterator i) if (!callee || DECL_BUILT_IN_CLASS (callee) != BUILT_IN_NORMAL /* All regular builtins are ok, just obviously not alloca. */ - || DECL_FUNCTION_CODE (callee) == BUILT_IN_ALLOCA) + || DECL_FUNCTION_CODE (callee) == BUILT_IN_ALLOCA + || DECL_FUNCTION_CODE (callee) == BUILT_IN_ALLOCA_WITH_ALIGN) return NULL_TREE; if (DECL_FUNCTION_CODE (callee) == BUILT_IN_STACK_RESTORE) diff --git a/gcc/tree-ssa-dce.c b/gcc/tree-ssa-dce.c index f225030de68..b84b6f9a99e 100644 --- a/gcc/tree-ssa-dce.c +++ b/gcc/tree-ssa-dce.c @@ -308,6 +308,7 @@ mark_stmt_if_obviously_necessary (gimple stmt, bool aggressive) case BUILT_IN_MALLOC: case BUILT_IN_CALLOC: case BUILT_IN_ALLOCA: + case BUILT_IN_ALLOCA_WITH_ALIGN: return; default:; @@ -639,6 +640,7 @@ mark_all_reaching_defs_necessary_1 (ao_ref *ref ATTRIBUTE_UNUSED, case BUILT_IN_MALLOC: case BUILT_IN_CALLOC: case BUILT_IN_ALLOCA: + case BUILT_IN_ALLOCA_WITH_ALIGN: case BUILT_IN_FREE: return false; @@ -890,6 +892,8 @@ propagate_necessity (struct edge_list *el) || DECL_FUNCTION_CODE (callee) == BUILT_IN_FREE || DECL_FUNCTION_CODE (callee) == BUILT_IN_VA_END || DECL_FUNCTION_CODE (callee) == BUILT_IN_ALLOCA + || (DECL_FUNCTION_CODE (callee) + == BUILT_IN_ALLOCA_WITH_ALIGN) || DECL_FUNCTION_CODE (callee) == BUILT_IN_STACK_SAVE || DECL_FUNCTION_CODE (callee) == BUILT_IN_STACK_RESTORE || DECL_FUNCTION_CODE (callee) == BUILT_IN_ASSUME_ALIGNED)) diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c index 3902b5ce5c9..8bfc91aae4f 100644 --- a/gcc/tree-ssa-dom.c +++ b/gcc/tree-ssa-dom.c @@ -1995,17 +1995,6 @@ cprop_operand (gimple stmt, use_operand_p op_p) val = SSA_NAME_VALUE (op); if (val && val != op) { - /* Do not change the base variable in the virtual operand - tables. That would make it impossible to reconstruct - the renamed virtual operand if we later modify this - statement. Also only allow the new value to be an SSA_NAME - for propagation into virtual operands. */ - if (!is_gimple_reg (op) - && (TREE_CODE (val) != SSA_NAME - || is_gimple_reg (val) - || get_virtual_var (val) != get_virtual_var (op))) - return; - /* Do not replace hard register operands in asm statements. */ if (gimple_code (stmt) == GIMPLE_ASM && !may_propagate_copy_into_asm (op)) @@ -2076,11 +2065,8 @@ cprop_into_stmt (gimple stmt) use_operand_p op_p; ssa_op_iter iter; - FOR_EACH_SSA_USE_OPERAND (op_p, stmt, iter, SSA_OP_ALL_USES) - { - if (TREE_CODE (USE_FROM_PTR (op_p)) == SSA_NAME) - cprop_operand (stmt, op_p); - } + FOR_EACH_SSA_USE_OPERAND (op_p, stmt, iter, SSA_OP_USE) + cprop_operand (stmt, op_p); } /* Optimize the statement pointed to by iterator SI. @@ -2107,18 +2093,18 @@ optimize_stmt (basic_block bb, gimple_stmt_iterator si) old_stmt = stmt = gsi_stmt (si); - if (gimple_code (stmt) == GIMPLE_COND) - canonicalize_comparison (stmt); - - update_stmt_if_modified (stmt); - opt_stats.num_stmts++; - if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, "Optimizing statement "); print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); } + if (gimple_code (stmt) == GIMPLE_COND) + canonicalize_comparison (stmt); + + update_stmt_if_modified (stmt); + opt_stats.num_stmts++; + /* Const/copy propagate into USES, VUSES and the RHS of VDEFs. */ cprop_into_stmt (stmt); diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c index c6b92cfe77f..de782c9be9f 100644 --- a/gcc/tree-ssa-forwprop.c +++ b/gcc/tree-ssa-forwprop.c @@ -465,16 +465,15 @@ forward_propagate_into_comparison (gimple_stmt_iterator *gsi) gimple stmt = gsi_stmt (*gsi); tree tmp; bool cfg_changed = false; + tree type = TREE_TYPE (gimple_assign_lhs (stmt)); tree rhs1 = gimple_assign_rhs1 (stmt); tree rhs2 = gimple_assign_rhs2 (stmt); /* Combine the comparison with defining statements. */ tmp = forward_propagate_into_comparison_1 (stmt, gimple_assign_rhs_code (stmt), - TREE_TYPE - (gimple_assign_lhs (stmt)), - rhs1, rhs2); - if (tmp) + type, rhs1, rhs2); + if (tmp && useless_type_conversion_p (type, TREE_TYPE (tmp))) { gimple_assign_set_rhs_from_tree (gsi, tmp); fold_stmt (gsi); @@ -804,11 +803,6 @@ forward_propagate_addr_expr_1 (tree name, tree def_rhs, && ((rhs_code == SSA_NAME && rhs == name) || CONVERT_EXPR_CODE_P (rhs_code))) { - /* Don't propagate restrict pointer's RHS. */ - if (TYPE_RESTRICT (TREE_TYPE (lhs)) - && !TYPE_RESTRICT (TREE_TYPE (name)) - && !is_gimple_min_invariant (def_rhs)) - return false; /* Only recurse if we don't deal with a single use or we cannot do the propagation to the current statement. In particular we can end up with a conversion needed for a non-invariant diff --git a/gcc/tree-ssa-operands.c b/gcc/tree-ssa-operands.c index d1630371fe5..9cd656b2a8c 100644 --- a/gcc/tree-ssa-operands.c +++ b/gcc/tree-ssa-operands.c @@ -943,7 +943,7 @@ get_expr_operands (gimple stmt, tree *expr_p, int flags) case COND_EXPR: case VEC_COND_EXPR: - case VEC_SHUFFLE_EXPR: + case VEC_PERM_EXPR: get_expr_operands (stmt, &TREE_OPERAND (expr, 0), uflags); get_expr_operands (stmt, &TREE_OPERAND (expr, 1), uflags); get_expr_operands (stmt, &TREE_OPERAND (expr, 2), uflags); diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index 3b1ad3da269..c33b87dd7fe 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -1489,7 +1489,66 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_) } } - /* 4) For aggregate copies translate the reference through them if + /* 4) Assignment from an SSA name which definition we may be able + to access pieces from. */ + else if (ref->size == maxsize + && is_gimple_reg_type (vr->type) + && gimple_assign_single_p (def_stmt) + && TREE_CODE (gimple_assign_rhs1 (def_stmt)) == SSA_NAME) + { + tree rhs1 = gimple_assign_rhs1 (def_stmt); + gimple def_stmt2 = SSA_NAME_DEF_STMT (rhs1); + if (is_gimple_assign (def_stmt2) + && (gimple_assign_rhs_code (def_stmt2) == COMPLEX_EXPR + || gimple_assign_rhs_code (def_stmt2) == CONSTRUCTOR) + && types_compatible_p (vr->type, TREE_TYPE (TREE_TYPE (rhs1)))) + { + tree base2; + HOST_WIDE_INT offset2, size2, maxsize2, off; + base2 = get_ref_base_and_extent (gimple_assign_lhs (def_stmt), + &offset2, &size2, &maxsize2); + off = offset - offset2; + if (maxsize2 != -1 + && maxsize2 == size2 + && operand_equal_p (base, base2, 0) + && offset2 <= offset + && offset2 + size2 >= offset + maxsize) + { + tree val = NULL_TREE; + HOST_WIDE_INT elsz + = TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (TREE_TYPE (rhs1)))); + if (gimple_assign_rhs_code (def_stmt2) == COMPLEX_EXPR) + { + if (off == 0) + val = gimple_assign_rhs1 (def_stmt2); + else if (off == elsz) + val = gimple_assign_rhs2 (def_stmt2); + } + else if (gimple_assign_rhs_code (def_stmt2) == CONSTRUCTOR + && off % elsz == 0) + { + tree ctor = gimple_assign_rhs1 (def_stmt2); + unsigned i = off / elsz; + if (i < CONSTRUCTOR_NELTS (ctor)) + { + constructor_elt *elt = CONSTRUCTOR_ELT (ctor, i); + if (compare_tree_int (elt->index, i) == 0) + val = elt->value; + } + } + if (val) + { + unsigned int value_id = get_or_alloc_constant_value_id (val); + return vn_reference_insert_pieces + (vuse, vr->set, vr->type, + VEC_copy (vn_reference_op_s, heap, vr->operands), + val, value_id); + } + } + } + } + + /* 5) For aggregate copies translate the reference through them if the copy kills ref. */ else if (vn_walk_kind == VN_WALKREWRITE && gimple_assign_single_p (def_stmt) @@ -1587,7 +1646,7 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_) return NULL; } - /* 5) For memcpy copies translate the reference through them if + /* 6) For memcpy copies translate the reference through them if the copy kills ref. */ else if (vn_walk_kind == VN_WALKREWRITE && is_gimple_reg_type (vr->type) diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c index 821fc7d92b2..7de22aabcb3 100644 --- a/gcc/tree-ssa-structalias.c +++ b/gcc/tree-ssa-structalias.c @@ -4494,15 +4494,6 @@ find_func_aliases (gimple origt) && (!in_ipa_mode || DECL_EXTERNAL (lhsop) || TREE_PUBLIC (lhsop))) make_escape_constraint (rhsop); - /* If this is a conversion of a non-restrict pointer to a - restrict pointer track it with a new heapvar. */ - else if (gimple_assign_cast_p (t) - && POINTER_TYPE_P (TREE_TYPE (rhsop)) - && POINTER_TYPE_P (TREE_TYPE (lhsop)) - && !TYPE_RESTRICT (TREE_TYPE (rhsop)) - && TYPE_RESTRICT (TREE_TYPE (lhsop))) - make_constraint_from_restrict (get_vi_for_tree (lhsop), - "CAST_RESTRICT"); } /* Handle escapes through return. */ else if (gimple_code (t) == GIMPLE_RETURN diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c index a0115938077..258a7444b08 100644 --- a/gcc/tree-ssa.c +++ b/gcc/tree-ssa.c @@ -1270,12 +1270,6 @@ useless_type_conversion_p (tree outer_type, tree inner_type) != TYPE_ADDR_SPACE (TREE_TYPE (inner_type))) return false; - /* Do not lose casts to restrict qualified pointers. */ - if ((TYPE_RESTRICT (outer_type) - != TYPE_RESTRICT (inner_type)) - && TYPE_RESTRICT (outer_type)) - return false; - /* If the outer type is (void *), the conversion is not necessary. */ if (VOID_TYPE_P (TREE_TYPE (outer_type))) return true; diff --git a/gcc/tree-vect-generic.c b/gcc/tree-vect-generic.c index ef03b355f78..1d1170121b4 100644 --- a/gcc/tree-vect-generic.c +++ b/gcc/tree-vect-generic.c @@ -536,6 +536,17 @@ vector_element (gimple_stmt_iterator *gsi, tree vect, tree idx, tree *ptmpvec) idx = build_int_cst (TREE_TYPE (idx), index); } + /* When lowering a vector statement sequence do some easy + simplification by looking through intermediate vector results. */ + if (TREE_CODE (vect) == SSA_NAME) + { + gimple def_stmt = SSA_NAME_DEF_STMT (vect); + if (is_gimple_assign (def_stmt) + && (gimple_assign_rhs_code (def_stmt) == VECTOR_CST + || gimple_assign_rhs_code (def_stmt) == CONSTRUCTOR)) + vect = gimple_assign_rhs1 (def_stmt); + } + if (TREE_CODE (vect) == VECTOR_CST) { unsigned i; @@ -586,21 +597,21 @@ vector_element (gimple_stmt_iterator *gsi, tree vect, tree idx, tree *ptmpvec) idx, NULL_TREE, NULL_TREE); } -/* Check if VEC_SHUFFLE_EXPR within the given setting is supported +/* Check if VEC_PERM_EXPR within the given setting is supported by hardware, or lower it piecewise. - When VEC_SHUFFLE_EXPR has the same first and second operands: - VEC_SHUFFLE_EXPR <v0, v0, mask> the lowered version would be + When VEC_PERM_EXPR has the same first and second operands: + VEC_PERM_EXPR <v0, v0, mask> the lowered version would be {v0[mask[0]], v0[mask[1]], ...} MASK and V0 must have the same number of elements. - Otherwise VEC_SHUFFLE_EXPR <v0, v1, mask> is lowered to + Otherwise VEC_PERM_EXPR <v0, v1, mask> is lowered to {mask[0] < len(v0) ? v0[mask[0]] : v1[mask[0]], ...} V0 and V1 must have the same type. MASK, V0, V1 must have the same number of arguments. */ static void -lower_vec_shuffle (gimple_stmt_iterator *gsi) +lower_vec_perm (gimple_stmt_iterator *gsi) { gimple stmt = gsi_stmt (*gsi); tree mask = gimple_assign_rhs3 (stmt); @@ -617,7 +628,7 @@ lower_vec_shuffle (gimple_stmt_iterator *gsi) bool two_operand_p = !operand_equal_p (vec0, vec1, 0); unsigned i; - if (expand_vec_shuffle_expr_p (TYPE_MODE (vect_type), vec0, vec1, mask)) + if (expand_vec_perm_expr_p (TYPE_MODE (vect_type), vec0, vec1, mask)) return; v = VEC_alloc (constructor_elt, gc, elements); @@ -710,9 +721,9 @@ expand_vector_operations_1 (gimple_stmt_iterator *gsi) rhs_class = get_gimple_rhs_class (code); lhs = gimple_assign_lhs (stmt); - if (code == VEC_SHUFFLE_EXPR) + if (code == VEC_PERM_EXPR) { - lower_vec_shuffle (gsi); + lower_vec_perm (gsi); return; } diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c index 5ed60b79552..44a37b91e38 100644 --- a/gcc/tree-vect-patterns.c +++ b/gcc/tree-vect-patterns.c @@ -49,12 +49,15 @@ static gimple vect_recog_dot_prod_pattern (VEC (gimple, heap) **, tree *, static gimple vect_recog_pow_pattern (VEC (gimple, heap) **, tree *, tree *); static gimple vect_recog_over_widening_pattern (VEC (gimple, heap) **, tree *, tree *); +static gimple vect_recog_mixed_size_cond_pattern (VEC (gimple, heap) **, + tree *, tree *); static vect_recog_func_ptr vect_vect_recog_func_ptrs[NUM_PATTERNS] = { vect_recog_widen_mult_pattern, vect_recog_widen_sum_pattern, vect_recog_dot_prod_pattern, vect_recog_pow_pattern, - vect_recog_over_widening_pattern}; + vect_recog_over_widening_pattern, + vect_recog_mixed_size_cond_pattern}; /* Function widened_name_p @@ -385,6 +388,7 @@ vect_handle_widen_mult_by_const (gimple stmt, tree const_oprnd, tree *oprnd, || TREE_TYPE (gimple_assign_lhs (new_stmt)) != new_type) return false; + VEC_safe_push (gimple, heap, *stmts, def_stmt); *oprnd = gimple_assign_lhs (new_stmt); } else @@ -396,7 +400,6 @@ vect_handle_widen_mult_by_const (gimple stmt, tree const_oprnd, tree *oprnd, new_oprnd = make_ssa_name (tmp, NULL); new_stmt = gimple_build_assign_with_ops (NOP_EXPR, new_oprnd, *oprnd, NULL_TREE); - SSA_NAME_DEF_STMT (new_oprnd) = new_stmt; STMT_VINFO_RELATED_STMT (vinfo_for_stmt (def_stmt)) = new_stmt; VEC_safe_push (gimple, heap, *stmts, def_stmt); *oprnd = new_oprnd; @@ -615,7 +618,6 @@ vect_recog_widen_mult_pattern (VEC (gimple, heap) **stmts, var = vect_recog_temp_ssa_var (type, NULL); pattern_stmt = gimple_build_assign_with_ops (WIDEN_MULT_EXPR, var, oprnd0, oprnd1); - SSA_NAME_DEF_STMT (var) = pattern_stmt; if (vect_print_dump_info (REPORT_DETAILS)) print_gimple_stmt (vect_dump, pattern_stmt, 0, TDF_SLIM); @@ -699,7 +701,6 @@ vect_recog_pow_pattern (VEC (gimple, heap) **stmts, tree *type_in, var = vect_recog_temp_ssa_var (TREE_TYPE (base), NULL); stmt = gimple_build_assign_with_ops (MULT_EXPR, var, base, base); - SSA_NAME_DEF_STMT (var) = stmt; return stmt; } @@ -822,7 +823,6 @@ vect_recog_widen_sum_pattern (VEC (gimple, heap) **stmts, tree *type_in, var = vect_recog_temp_ssa_var (type, NULL); pattern_stmt = gimple_build_assign_with_ops (WIDEN_SUM_EXPR, var, oprnd0, oprnd1); - SSA_NAME_DEF_STMT (var) = pattern_stmt; if (vect_print_dump_info (REPORT_DETAILS)) { @@ -1012,7 +1012,6 @@ vect_operation_fits_smaller_type (gimple stmt, tree def, tree *new_type, new_oprnd = make_ssa_name (tmp, NULL); new_stmt = gimple_build_assign_with_ops (NOP_EXPR, new_oprnd, oprnd, NULL_TREE); - SSA_NAME_DEF_STMT (new_oprnd) = new_stmt; STMT_VINFO_RELATED_STMT (vinfo_for_stmt (def_stmt)) = new_stmt; VEC_safe_push (gimple, heap, *stmts, def_stmt); oprnd = new_oprnd; @@ -1034,7 +1033,6 @@ vect_operation_fits_smaller_type (gimple stmt, tree def, tree *new_type, new_oprnd = make_ssa_name (tmp, NULL); new_stmt = gimple_build_assign_with_ops (NOP_EXPR, new_oprnd, oprnd, NULL_TREE); - SSA_NAME_DEF_STMT (new_oprnd) = new_stmt; oprnd = new_oprnd; *new_def_stmt = new_stmt; } @@ -1137,9 +1135,9 @@ vect_recog_over_widening_pattern (VEC (gimple, heap) **stmts, VEC_safe_push (gimple, heap, *stmts, prev_stmt); var = vect_recog_temp_ssa_var (new_type, NULL); - pattern_stmt = gimple_build_assign_with_ops ( - gimple_assign_rhs_code (stmt), var, op0, op1); - SSA_NAME_DEF_STMT (var) = pattern_stmt; + pattern_stmt + = gimple_build_assign_with_ops (gimple_assign_rhs_code (stmt), var, + op0, op1); STMT_VINFO_RELATED_STMT (vinfo_for_stmt (stmt)) = pattern_stmt; STMT_VINFO_PATTERN_DEF_STMT (vinfo_for_stmt (stmt)) = new_def_stmt; @@ -1178,7 +1176,6 @@ vect_recog_over_widening_pattern (VEC (gimple, heap) **stmts, new_oprnd = make_ssa_name (tmp, NULL); pattern_stmt = gimple_build_assign_with_ops (NOP_EXPR, new_oprnd, var, NULL_TREE); - SSA_NAME_DEF_STMT (new_oprnd) = pattern_stmt; STMT_VINFO_RELATED_STMT (vinfo_for_stmt (use_stmt)) = pattern_stmt; *type_in = get_vectype_for_scalar_type (new_type); @@ -1218,6 +1215,124 @@ vect_recog_over_widening_pattern (VEC (gimple, heap) **stmts, } +/* Function vect_recog_mixed_size_cond_pattern + + Try to find the following pattern: + + type x_t, y_t; + TYPE a_T, b_T, c_T; + loop: + S1 a_T = x_t CMP y_t ? b_T : c_T; + + where type 'TYPE' is an integral type which has different size + from 'type'. b_T and c_T are constants and if 'TYPE' is wider + than 'type', the constants need to fit into an integer type + with the same width as 'type'. + + Input: + + * LAST_STMT: A stmt from which the pattern search begins. + + Output: + + * TYPE_IN: The type of the input arguments to the pattern. + + * TYPE_OUT: The type of the output of this pattern. + + * Return value: A new stmt that will be used to replace the pattern. + Additionally a def_stmt is added. + + a_it = x_t CMP y_t ? b_it : c_it; + a_T = (TYPE) a_it; */ + +static gimple +vect_recog_mixed_size_cond_pattern (VEC (gimple, heap) **stmts, tree *type_in, + tree *type_out) +{ + gimple last_stmt = VEC_index (gimple, *stmts, 0); + tree cond_expr, then_clause, else_clause; + stmt_vec_info stmt_vinfo = vinfo_for_stmt (last_stmt), def_stmt_info; + tree type, vectype, comp_vectype, itype, vecitype; + enum machine_mode cmpmode; + gimple pattern_stmt, def_stmt; + loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo); + + if (!is_gimple_assign (last_stmt) + || gimple_assign_rhs_code (last_stmt) != COND_EXPR + || STMT_VINFO_DEF_TYPE (stmt_vinfo) != vect_internal_def) + return NULL; + + cond_expr = gimple_assign_rhs1 (last_stmt); + then_clause = gimple_assign_rhs2 (last_stmt); + else_clause = gimple_assign_rhs3 (last_stmt); + + if (TREE_CODE (then_clause) != INTEGER_CST + || TREE_CODE (else_clause) != INTEGER_CST) + return NULL; + + if (!COMPARISON_CLASS_P (cond_expr)) + return NULL; + + comp_vectype + = get_vectype_for_scalar_type (TREE_TYPE (TREE_OPERAND (cond_expr, 0))); + if (comp_vectype == NULL_TREE) + return NULL; + + type = gimple_expr_type (last_stmt); + cmpmode = GET_MODE_INNER (TYPE_MODE (comp_vectype)); + + if (GET_MODE_BITSIZE (TYPE_MODE (type)) == GET_MODE_BITSIZE (cmpmode)) + return NULL; + + vectype = get_vectype_for_scalar_type (type); + if (vectype == NULL_TREE) + return NULL; + + if (expand_vec_cond_expr_p (vectype, comp_vectype)) + return NULL; + + itype = build_nonstandard_integer_type (GET_MODE_BITSIZE (cmpmode), + TYPE_UNSIGNED (type)); + if (itype == NULL_TREE + || GET_MODE_BITSIZE (TYPE_MODE (itype)) != GET_MODE_BITSIZE (cmpmode)) + return NULL; + + vecitype = get_vectype_for_scalar_type (itype); + if (vecitype == NULL_TREE) + return NULL; + + if (!expand_vec_cond_expr_p (vecitype, comp_vectype)) + return NULL; + + if (GET_MODE_BITSIZE (TYPE_MODE (type)) > GET_MODE_BITSIZE (cmpmode)) + { + if (!int_fits_type_p (then_clause, itype) + || !int_fits_type_p (else_clause, itype)) + return NULL; + } + + def_stmt + = gimple_build_assign_with_ops3 (COND_EXPR, + vect_recog_temp_ssa_var (itype, NULL), + unshare_expr (cond_expr), + fold_convert (itype, then_clause), + fold_convert (itype, else_clause)); + pattern_stmt + = gimple_build_assign_with_ops (NOP_EXPR, + vect_recog_temp_ssa_var (type, NULL), + gimple_assign_lhs (def_stmt), NULL_TREE); + + STMT_VINFO_PATTERN_DEF_STMT (stmt_vinfo) = def_stmt; + def_stmt_info = new_stmt_vec_info (def_stmt, loop_vinfo, NULL); + set_vinfo_for_stmt (def_stmt, def_stmt_info); + STMT_VINFO_VECTYPE (def_stmt_info) = vecitype; + *type_in = vecitype; + *type_out = vectype; + + return pattern_stmt; +} + + /* Mark statements that are involved in a pattern. */ static inline void @@ -1245,14 +1360,18 @@ vect_mark_pattern_stmts (gimple orig_stmt, gimple pattern_stmt, if (STMT_VINFO_PATTERN_DEF_STMT (pattern_stmt_info)) { def_stmt = STMT_VINFO_PATTERN_DEF_STMT (pattern_stmt_info); - set_vinfo_for_stmt (def_stmt, - new_stmt_vec_info (def_stmt, loop_vinfo, NULL)); - gimple_set_bb (def_stmt, gimple_bb (orig_stmt)); def_stmt_info = vinfo_for_stmt (def_stmt); + if (def_stmt_info == NULL) + { + def_stmt_info = new_stmt_vec_info (def_stmt, loop_vinfo, NULL); + set_vinfo_for_stmt (def_stmt, def_stmt_info); + } + gimple_set_bb (def_stmt, gimple_bb (orig_stmt)); STMT_VINFO_RELATED_STMT (def_stmt_info) = orig_stmt; STMT_VINFO_DEF_TYPE (def_stmt_info) = STMT_VINFO_DEF_TYPE (orig_stmt_info); - STMT_VINFO_VECTYPE (def_stmt_info) = pattern_vectype; + if (STMT_VINFO_VECTYPE (def_stmt_info) == NULL_TREE) + STMT_VINFO_VECTYPE (def_stmt_info) = pattern_vectype; } } @@ -1279,10 +1398,9 @@ vect_mark_pattern_stmts (gimple orig_stmt, gimple pattern_stmt, for vect_recog_pattern. */ static void -vect_pattern_recog_1 ( - gimple (* vect_recog_func) (VEC (gimple, heap) **, tree *, tree *), - gimple_stmt_iterator si, - VEC (gimple, heap) **stmts_to_replace) +vect_pattern_recog_1 (vect_recog_func_ptr vect_recog_func, + gimple_stmt_iterator si, + VEC (gimple, heap) **stmts_to_replace) { gimple stmt = gsi_stmt (si), pattern_stmt; stmt_vec_info stmt_info; @@ -1307,8 +1425,6 @@ vect_pattern_recog_1 ( { /* No need to check target support (already checked by the pattern recognition function). */ - if (type_out) - gcc_assert (VECTOR_MODE_P (TYPE_MODE (type_out))); pattern_vectype = type_out ? type_out : type_in; } else @@ -1466,7 +1582,7 @@ vect_pattern_recog (loop_vec_info loop_vinfo) unsigned int nbbs = loop->num_nodes; gimple_stmt_iterator si; unsigned int i, j; - gimple (* vect_recog_func_ptr) (VEC (gimple, heap) **, tree *, tree *); + vect_recog_func_ptr vect_recog_func; VEC (gimple, heap) *stmts_to_replace = VEC_alloc (gimple, heap, 1); if (vect_print_dump_info (REPORT_DETAILS)) @@ -1482,8 +1598,8 @@ vect_pattern_recog (loop_vec_info loop_vinfo) /* Scan over all generic vect_recog_xxx_pattern functions. */ for (j = 0; j < NUM_PATTERNS; j++) { - vect_recog_func_ptr = vect_vect_recog_func_ptrs[j]; - vect_pattern_recog_1 (vect_recog_func_ptr, si, + vect_recog_func = vect_vect_recog_func_ptrs[j]; + vect_pattern_recog_1 (vect_recog_func, si, &stmts_to_replace); } } diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index 8c2edadba13..f2ac8c7a616 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -652,9 +652,25 @@ vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo) have to scan the RHS or function arguments instead. */ if (is_gimple_assign (stmt)) { - for (i = 1; i < gimple_num_ops (stmt); i++) + enum tree_code rhs_code = gimple_assign_rhs_code (stmt); + tree op = gimple_assign_rhs1 (stmt); + + i = 1; + if (rhs_code == COND_EXPR && COMPARISON_CLASS_P (op)) + { + if (!process_use (stmt, TREE_OPERAND (op, 0), loop_vinfo, + live_p, relevant, &worklist) + || !process_use (stmt, TREE_OPERAND (op, 1), loop_vinfo, + live_p, relevant, &worklist)) + { + VEC_free (gimple, heap, worklist); + return false; + } + i = 2; + } + for (; i < gimple_num_ops (stmt); i++) { - tree op = gimple_op (stmt, i); + op = gimple_op (stmt, i); if (!process_use (stmt, op, loop_vinfo, live_p, relevant, &worklist)) { diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h index 3fe8b620c15..f22add6b754 100644 --- a/gcc/tree-vectorizer.h +++ b/gcc/tree-vectorizer.h @@ -1,5 +1,5 @@ /* Vectorizer - Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 + Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. Contributed by Dorit Naishlos <dorit@il.ibm.com> @@ -902,7 +902,7 @@ extern void vect_slp_transform_bb (basic_block); Additional pattern recognition functions can (and will) be added in the future. */ typedef gimple (* vect_recog_func_ptr) (VEC (gimple, heap) **, tree *, tree *); -#define NUM_PATTERNS 5 +#define NUM_PATTERNS 6 void vect_pattern_recog (loop_vec_info); /* In tree-vectorizer.c. */ diff --git a/gcc/tree.c b/gcc/tree.c index 3e9750383e1..03edb9c0324 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -9483,9 +9483,18 @@ build_common_builtin_nodes (void) "alloca", ECF_MALLOC | ECF_NOTHROW | ECF_LEAF); } + ftype = build_function_type_list (ptr_type_node, size_type_node, + size_type_node, NULL_TREE); + local_define_builtin ("__builtin_alloca_with_align", ftype, + BUILT_IN_ALLOCA_WITH_ALIGN, "alloca", + ECF_MALLOC | ECF_NOTHROW | ECF_LEAF); + /* If we're checking the stack, `alloca' can throw. */ if (flag_stack_check) - TREE_NOTHROW (built_in_decls[BUILT_IN_ALLOCA]) = 0; + { + TREE_NOTHROW (built_in_decls[BUILT_IN_ALLOCA]) = 0; + TREE_NOTHROW (built_in_decls[BUILT_IN_ALLOCA_WITH_ALIGN]) = 0; + } ftype = build_function_type_list (void_type_node, ptr_type_node, ptr_type_node, diff --git a/gcc/tree.def b/gcc/tree.def index 44c4ee8e717..3e5981947fd 100644 --- a/gcc/tree.def +++ b/gcc/tree.def @@ -497,18 +497,19 @@ DEFTREECODE (COND_EXPR, "cond_expr", tcc_expression, 3) */ DEFTREECODE (VEC_COND_EXPR, "vec_cond_expr", tcc_expression, 3) -/* Vector shuffle expression. A = VEC_SHUFFLE_EXPR<v0, v1, mask> - means +/* Vector permutation expression. A = VEC_PERM_EXPR<v0, v1, mask> means - foreach i in length (mask): - A = mask[i] < length (v0) ? v0[mask[i]] : v1[mask[i] - length (mask)] + N = length(mask) + foreach i in N: + M = mask[i] % (2*N) + A = M < N ? v0[M] : v1[M-N] V0 and V1 are vectors of the same type. MASK is an integer-typed vector. The number of MASK elements must be the same with the number of elements in V0 and V1. The size of the inner type of the MASK and of the V0 and V1 must be the same. */ -DEFTREECODE (VEC_SHUFFLE_EXPR, "vec_shuffle_expr", tcc_expression, 3) +DEFTREECODE (VEC_PERM_EXPR, "vec_perm_expr", tcc_expression, 3) /* Declare local variables, including making RTL and allocating space. BIND_EXPR_VARS is a chain of VAR_DECL nodes for the variables. diff --git a/gcc/tree.h b/gcc/tree.h index f064bbe30f5..e0f1a075037 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -5352,6 +5352,7 @@ fold_build_pointer_plus_hwi_loc (location_t loc, tree ptr, HOST_WIDE_INT off) fold_build_pointer_plus_hwi_loc (UNKNOWN_LOCATION, p, o) /* In builtins.c */ +extern bool avoid_folding_inline_builtin (tree); extern tree fold_call_expr (location_t, tree, bool); extern tree fold_builtin_fputs (location_t, tree, tree, bool, bool, tree); extern tree fold_builtin_strcpy (location_t, tree, tree, tree, tree); diff --git a/gcc/varasm.c b/gcc/varasm.c index 9b4dfad5cbb..94e31115d1e 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -2104,7 +2104,8 @@ incorporeal_function_p (tree decl) const char *name; if (DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL - && DECL_FUNCTION_CODE (decl) == BUILT_IN_ALLOCA) + && (DECL_FUNCTION_CODE (decl) == BUILT_IN_ALLOCA + || DECL_FUNCTION_CODE (decl) == BUILT_IN_ALLOCA_WITH_ALIGN)) return true; name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); |