-2013-11-18 Jan Hubicka <jh@suse.cz>
+2013-12-03 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
- * config/bootstrap-lto.mk: Use -ffat-lto-objects.
+ * MAINTAINERS: Add self as SLSR maintainer.
+
+2013-11-18 Jan Hubicka <hubicka@ucw.cz>
+
+ * MAINTAINERS: Update my email address.
2013-11-15 David Edelsohn <dje.gcc@gmail.com>
2013-01-23 Shenghou Ma <minux.ma@gmail.com>
- * config/isl.m4: don't echo $CFLAGS for ISL_CHECK_VERSION.
* configure: Re-generate.
2013-01-15 Richard Biener <rguenther@suse.de>
hppa port Jeff Law law@redhat.com
hppa port John David Anglin dave.anglin@nrc-cnrc.gc.ca
i386 port Richard Henderson rth@redhat.com
-i386 port Jan Hubicka jh@suse.cz
+i386 port Jan Hubicka hubicka@ucw.cz
i386 port Uros Bizjak ubizjak@gmail.com
ia64 port Jim Wilson wilson@tuliptree.org
ia64 port Steve Ellcey sellcey@mips.com
tilepro port Walter Lee walt@tilera.com
v850 port Nick Clifton nickc@redhat.com
vax port Matt Thomas matt@3am-software.com
-x86-64 port Jan Hubicka jh@suse.cz
+x86-64 port Jan Hubicka hubicka@ucw.cz
xstormy16 port Nick Clifton nickc@redhat.com
xtensa port Sterling Augustine augustine.sterling@gmail.com
modulo-scheduler Ayal Zaks zaks@il.ibm.com
reorg Jeff Law law@redhat.com
caller-save.c Jeff Law law@redhat.com
-callgraph Jan Hubicka jh@suse.cz
+callgraph Jan Hubicka hubicka@ucw.cz
debugging code Jim Wilson wilson@tuliptree.org
dwarf debugging code Jason Merrill jason@redhat.com
dwarf debugging code Cary Coutant ccoutant@google.com
docstring relicensing Diego Novillo dnovillo@google.com
docstring relicensing Gerald Pfeifer gerald@pfeifer.com
docstring relicensing Joseph Myers joseph@codesourcery.com
-predict.def Jan Hubicka jh@suse.cz
+predict.def Jan Hubicka hubicka@ucw.cz
contrib/regression Geoff Keating geoffk@geoffk.org
-gcov Jan Hubicka jh@suse.cz
+gcov Jan Hubicka hubicka@ucw.cz
gcov Nathan Sidwell nathan@codesourcery.com
option handling Neil Booth neil@daikokuya.co.uk
option handling Joseph Myers joseph@codesourcery.com
tree browser/unparser Sebastian Pop sebastian.pop@amd.com
scev, data dependence Daniel Berlin dberlin@dberlin.org
scev, data dependence Sebastian Pop sebastian.pop@amd.com
-profile feedback Jan Hubicka jh@suse.cz
+profile feedback Jan Hubicka hubicka@ucw.cz
type-safe vectors Nathan Sidwell nathan@codesourcery.com
alias analysis Daniel Berlin dberlin@dberlin.org
reload Ulrich Weigand uweigand@de.ibm.com
testsuite Janis Johnson janisjo@codesourcery.com
register allocation Vladimir Makarov vmakarov@redhat.com
gdbhooks.py David Malcolm dmalcolm@redhat.com
+SLSR Bill Schmidt wschmidt@linux.vnet.ibm.com
Note that individuals who maintain parts of the compiler need approval to
check in changes outside of the parts of the compiler they maintain.
+2013-11-29 Marek Polacek <polacek@redhat.com>
+
+ * bootstrap-ubsan.mk (POSTSTAGE1_LDFLAGS): Remove -lpthread -ldl.
+ Add -B$$r/prev-$(TARGET_SUBDIR)/libsanitizer/.
+
+2013-11-29 H.J. Lu <hongjiu.lu@intel.com>
+
+ * bootstrap-asan.mk (POSTSTAGE1_LDFLAGS): Add
+ -B$$r/prev-$(TARGET_SUBDIR)/libsanitizer/.
+
2013-11-19 Marek Polacek <polacek@redhat.com>
* bootstrap-ubsan.mk (POSTSTAGE1_LDFLAGS): Add -ldl.
+2013-11-18 Jan Hubicka <jh@suse.cz>
+
+ * bootstrap-lto.mk: Use -ffat-lto-objects.
+
2013-11-15 Andreas Schwab <schwab@linux-m68k.org>
* picflag.m4 (m68k-*-*): Use default PIC flag.
* bootstrap-asan.mk (POSTSTAGE1_LDFLAGS): Add
-B$$r/prev-$(TARGET_SUBDIR)/libsanitizer/asan/.
+2013-01-23 Shenghou Ma <minux.ma@gmail.com>
+
+ * isl.m4: don't echo $CFLAGS for ISL_CHECK_VERSION.
+
2013-01-15 Richard Biener <rguenther@suse.de>
PR other/55973
STAGE2_CFLAGS += -fsanitize=address
STAGE3_CFLAGS += -fsanitize=address
POSTSTAGE1_LDFLAGS += -fsanitize=address -static-libasan \
+ -B$$r/prev-$(TARGET_SUBDIR)/libsanitizer/ \
-B$$r/prev-$(TARGET_SUBDIR)/libsanitizer/asan/ \
-B$$r/prev-$(TARGET_SUBDIR)/libsanitizer/asan/.libs
STAGE2_CFLAGS += -fsanitize=undefined
STAGE3_CFLAGS += -fsanitize=undefined
-POSTSTAGE1_LDFLAGS += -fsanitize=undefined -static-libubsan -lpthread -ldl \
+POSTSTAGE1_LDFLAGS += -fsanitize=undefined -static-libubsan \
+ -B$$r/prev-$(TARGET_SUBDIR)/libsanitizer/ \
-B$$r/prev-$(TARGET_SUBDIR)/libsanitizer/ubsan/ \
-B$$r/prev-$(TARGET_SUBDIR)/libsanitizer/ubsan/.libs
+2013-12-04 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/59355
+ * ipa-devirt.c (gate_ipa_devirt): Return false if
+ !flag_devirtualize.
+ * opts.c (common_handle_option): Fix comment spelling.
+
+2013-12-04 Yufeng Zhang <yufeng.zhang@arm.com>
+
+ * gimple-ssa-strength-reduction.c: Include tree-affine.h.
+ (name_expansions): New static variable.
+ (alt_base_map): Ditto.
+ (get_alternative_base): New function.
+ (find_basis_for_candidate): For CAND_REF, optionally call
+ find_basis_for_base_expr with the returned value from
+ get_alternative_base.
+ (record_potential_basis): Add new parameter 'base' of type 'tree';
+ add an assertion of non-NULL base; use base to set node->base_expr.
+ (alloc_cand_and_find_basis): Update; call record_potential_basis
+ for CAND_REF with the returned value from get_alternative_base.
+ (replace_refs): Dump details on the replacing.
+ (execute_strength_reduction): Call pointer_map_create for
+ alt_base_map; call free_affine_expand_cache with &name_expansions.
+
+2013-12-03 Wei Mi <wmi@google.com>
+
+ PR rtl-optimization/59020
+ * sched-deps.c (try_group_insn): Move it from haifa-sched.c to here.
+ (sched_analyze_insn): Call try_group_insn.
+ (sched_analyze): Cleanup SCHED_GROUP_P before start the analysis.
+ * haifa-sched.c (try_group_insn): Moved to sched-deps.c.
+ (group_insns_for_macro_fusion): Removed.
+ (sched_init): Remove calling group_insns_for_macro_fusion.
+
+2013-12-03 Peter Bergner <bergner@vnet.ibm.com>
+
+ * config/rs6000/htmintrin.h (_TEXASR_INSTRUCTION_FETCH_CONFLICT): Fix
+ typo in macro name.
+ (_TEXASRU_INSTRUCTION_FETCH_CONFLICT): Likewise.
+
+2013-12-03 Vladimir Makarov <vmakarov@redhat.com>
+
+ * config/aarch64/aarch64.c (aarch64_frame_pointer_required): Check
+ LR_REGNUM.
+ (aarch64_can_eliminate): Don't check elimination source when
+ frame_pointer_required is false.
+
+2013-12-03 Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com>
+
+ * config/avr/avr.c (avr_option_override): Warn if asked to generate
+ position independent code.
+ * config/avr/avr.h: Modify LINK_SPEC to reject -shared.
+
+2013-12-03 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR target/59363
+ * config/i386/i386.c (emit_memset): Adjust destination address
+ after gen_strset.
+ (expand_setmem_epilogue): Likewise.
+
+2013-12-03 Marek Polacek <polacek@redhat.com>
+
+ PR middle-end/56344
+ * calls.c (expand_call): Disallow passing huge arguments
+ by value.
+
+2013-12-03 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/59362
+ * tree-object-size.c (object_sizes): Change into array of
+ vec<unsigned HOST_WIDE_INT>.
+ (compute_builtin_object_size): Check computed bitmap for
+ non-NULL instead of object_sizes. Call safe_grow on object_sizes
+ vector if new SSA_NAMEs appeared.
+ (init_object_sizes): Check computed bitmap for non-NULL.
+ Call safe_grow on object_sizes elements instead of initializing
+ it with XNEWVEC.
+ (fini_object_sizes): Call release on object_sizes elements, don't
+ set it to NULL.
+
+ PR middle-end/59011
+ * gimplify.c (nonlocal_vla_vars): New variable.
+ (gimplify_var_or_parm_decl): Put VAR_DECLs for VLAs into
+ nonlocal_vla_vars chain.
+ (gimplify_body): Call declare_vars on nonlocal_vla_vars chain
+ if outer_bind has DECL_INITIAL (current_function_decl) block.
+
+ PR target/58864
+ * dojump.c (save_pending_stack_adjust, restore_pending_stack_adjust):
+ New functions.
+ * expr.h (struct saved_pending_stack_adjust): New type.
+ (save_pending_stack_adjust, restore_pending_stack_adjust): New
+ prototypes.
+ * optabs.c (emit_conditional_move): Call save_pending_stack_adjust
+ and get_last_insn before do_pending_stack_adjust, call
+ restore_pending_stack_adjust after delete_insns_since.
+ * expr.c (expand_expr_real_2): Don't call do_pending_stack_adjust
+ before calling emit_conditional_move.
+ * expmed.c (expand_sdiv_pow2): Likewise.
+ * calls.c (expand_call): Use {save,restore}_pending_stack_adjust.
+
+2013-12-02 Jeff Law <law@redhat.com>
+
+ PR tree-optimization/59322
+ * tree-ssa-threadedge.c (create_edge_and_update_destination_phis):
+ Remove code which copied jump threading paths.
+
+2013-12-02 Sriraman Tallam <tmsriram@google.com>
+
+ PR target/58944
+ * config/i386/i386.opt (ix86_arch_string): Mark this variable
+ for saving in cl_target_option.
+ (ix86_tune_string): Ditto.
+ (ix86_cmodel): Ditto.
+ (ix86_abi): Ditto.
+ (ix86_asm_dialect): Ditto.
+ (ix86_branch_cost): Ditto.
+ (ix86_dump_tunes): Ditto.
+ (ix86_force_align_arg_pointer): Ditto.
+ (ix86_force_drap): Ditto.
+ (ix86_incoming_stack_boundary_arg): Ditto.
+ (ix86_pmode): Ditto.
+ (ix86_preferred_stack_boundary_arg): Ditto.
+ (ix86_recip_name): Ditto.
+ (ix86_regparm): Ditto.
+ (ix86_section_threshold): Ditto.
+ (ix86_sse2avx): Ditto.
+ (ix86_stack_protector_guard): Ditto.
+ (ix86_stringop_alg): Ditto.
+ (ix86_tls_dialect): Ditto.
+ (ix86_tune_ctrl_string): Ditto.
+ (ix86_tune_memcpy_strategy): Ditto.
+ (ix86_tune_memset_strategy): Ditto.
+ (ix86_tune_no_default): Ditto.
+ (ix86_veclibabi_type): Ditto.
+ * config/i386/i386.c
+ (function_specific_save): Save the above variables
+ in gcc_options to cl_target_option.
+ (function_specific_restore): Do the reverse done in
+ function_specific_save.
+ (ix86_valid_target_attribute_tree): Change ix86_arch_string
+ and ix86_tune_string to use the opts structure.
+ (ix86_option_override_internal):Change
+ ix86_incoming_stack_boundary_arg to
+ opts->x_ix86_incoming_stack_boundary_arg
+
+2013-12-02 Joern Rennecke <joern.rennecke@embecosm.com>
+
+ * config/epiphany/epiphany.h: Wrap rtl_opt_pass declarations
+ in #ifndef IN_LIBGCC2 / #endif.
+
+2013-12-02 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/59358
+ * tree-vrp.c (union_ranges): To check for the partially
+ overlapping ranges or adjacent ranges, also compare *vr0max
+ with vr1max.
+
+2013-12-02 Sterling Augustine <saugustine@google.com>
+
+ * dwarf2out.c (output_pubnames): Use comp_unit_die ()->die_offset
+ when there isn't a skeleton die.
+
+2013-12-02 Marek Polacek <polacek@redhat.com>
+
+ PR sanitizer/59353
+ * doc/invoke.texi: Document -fsanitize=return.
+
+2013-12-02 Tobias Burnus <burnus@net-b.de>
+ Manuel López-Ibáñez <manu@gcc.gnu.org>
+
+ PR middle-end/59257
+ * doc/invoke.texi: Add missing @opindex.
+ (-fsanitize=): Use @gcctabopt instead of @itemize.
+
+2013-12-02 Bernd Edlinger <bernd.edlinger@hotmail.de>
+
+ Fix C++0x memory model for unaligned fields in packed, aligned(4)
+ structures with -fno-strict-volatile-bitfields on STRICT_ALIGNMENT
+ targets like arm-none-eabi.
+ * expr.c (expand_assignment): Handle normal fields like bit regions.
+
+2013-12-02 Bernd Edlinger <bernd.edlinger@hotmail.de>
+
+ PR target/58115
+ * function.c (invoke_set_current_function_hook): Call
+ targetm.set_current_function after setting this_fn_optabs.
+
+2013-12-02 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/59139
+ * tree-ssa-loop-niter.c (chain_of_csts_start): Properly match
+ code in get_val_for.
+ (get_val_for): Use gcc_checking_asserts.
+
+2013-12-02 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/59199
+ * tree-ssa-operands.c (opf_implicit): Remove.
+ (opf_address_taken): New flag.
+ (get_expr_operands): Remove early out, pass down
+ opf_address_taken for ADDR_EXPRs, add a use operand only
+ for non-opf_address_taken bases.
+ (get_indirect_ref_operands): Rename to ...
+ (get_mem_ref_operands): ... this.
+ (get_asm_expr_operands): Rename to ...
+ (get_asm_stmt_operands): ... this.
+
+2013-12-02 Yuri Rumyantsev <ysrumyan@gmail.com>
+
+ * ipa-inline.c (check_callers): Add missed pointer de-reference.
+
+2013-12-02 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR tree-optimization/59356
+ * tree-dfa.h (get_addr_base_and_unit_offset_1) <case ARRAY_REF>: Do the
+ offset computation using the precision of the index type.
+
+2013-12-02 Yvan Roux <yvan.roux@linaro.org>
+
+ PR target/58785
+ * config/arm/arm.c (arm_preferred_reload_class): Only return LO_REGS
+ when rclass is GENERAL_REGS.
+
+2013-12-02 Ganesh Gopalasubramanian <Ganesh.Gopalasubramanian@amd.com>
+
+ * loop-unroll.c (decide_unroll_constant_iterations): Check macro
+ TARGET_LOOP_UNROLL_ADJUST while deciding unroll factor.
+
+2013-12-01 Eric Botcazou <ebotcazou@adacore.com>
+
+ * config/i386/winnt.c (i386_pe_asm_named_section): Be prepared for an
+ identifier node.
+
+2013-12-01 Bernd Edlinger <bernd.edlinger@hotmail.de>
+
+ * expr.c (emit_group_store): Fix off-by-one BITFIELD_END argument.
+
+2013-11-30 Paulo Matos <pmatos@broadcom.com>
+ Eric Botcazou <ebotcazou@adacore.com>
+
+ * combine.c (reg_nonzero_bits_for_combine): Apply mask transformation
+ as applied to nonzero_sign_valid when last_set_mode has less precision
+ than mode.
+
+2013-11-30 Tobias Burnus <burnus@net-b.de>
+
+ PR sanitizer/59275
+ * doc/invoke.texi (-fsanitize=address,leak): Mention the associated
+ environment variable and link to a list with flags.
+ (-fsanitize=thread): Ditto and update link.
+
+2013-11-29 Vladimir Makarov <vmakarov@redhat.com>
+
+ PR rtl-optimization/59340
+ * lra.c (check_rtl): Use recog_memoized instead of insn_invalid_p.
+
+ Revert
+ 2013-11-20 Robert Suchanek <Robert.Suchanek@imgtec.com>
+
+ * lra.c (lra): Set lra_in_progress before check_rtl call.
+ * recog.c (insn_invalid_p): Add !lra_in_progress to prevent
+ adding clobber regs when LRA is running.
+
+2013-11-29 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ PR target/59289
+ * config/arm/arm.c (cortexa15_extra_costs): Adjust costs.
+
+2013-11-29 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/59208
+ * tree-ssa-operands.h (fini_ssa_operands, verify_ssa_operands,
+ free_stmt_operands, update_stmt_operands): Add struct function
+ argument.
+ * tree-ssa-operands.c: Remove uses of cfun, propagate struct
+ function argument from fini_ssa_operands, verify_ssa_operands,
+ free_stmt_operands and update_stmt_operands everywhere.
+ * tree-ssanames.h (release_ssa_name_fn): New.
+ (release_ssa_name): Inline wrapper around release_ssa_name_fn.
+ * tree-ssanames.c (release_ssa_name): Rename to ...
+ (release_ssa_name_fn): ... this and add struct function argument.
+ * gimple-ssa.h (update_stmt, update_stmt_if_modified): Adjust.
+ (update_stmt_fn): New function.
+ * tree-cfg.c (move_block_to_fn): Adjust.
+ * tree-if-conv.c (free_bb_predicate): Likewise.
+ * tree-ssa.c (verify_ssa): Likewise.
+ (delete_tree_ssa): Likewise.
+ * gimple-pretty-print.c (dump_gimple_mem_ops): Remove guard.
+ * cgraph.c (cgraph_redirect_edge_call_stmt_to_callee): Call
+ update_stmt_fn instead of update_stmt.
+
+2013-11-29 Yvan Roux <yvan.roux@linaro.org>
+
+ * config/arm/arm.h (THUMB_SECONDARY_INPUT_RELOAD_CLASS): Return NO_REGS
+ for LRA.
+
+2013-11-29 Yvan Roux <yvan.roux@linaro.org>
+
+ * config/arm/arm.md (store_minmaxsi): Use only when
+ optimize_function_for_size_p.
+
+2013-11-29 Jakub Jelinek <jakub@redhat.com>
+ Yury Gribov <y.gribov@samsung.com>
+
+ PR sanitizer/59063
+ * config/gnu-user.h: Removed old code for setting up sanitizer
+ libs.
+ * gcc.c: Using libsanitizer spec instead of explicit libs.
+
+2013-11-29 Ilya Enkovich <ilya.enkovich@intel.com>
+
+ Reverted:
+ 2013-11-20 Ilya Enkovich <ilya.enkovich@intel.com>
+ * cgraph.h (varpool_node): Add need_bounds_init field.
+ * lto-cgraph.c (lto_output_varpool_node): Output
+ need_bounds_init value.
+ (input_varpool_node): Read need_bounds_init value.
+ * varpool.c (dump_varpool_node): Dump need_bounds_init field.
+
+ Reverted:
+ 2013-11-20 Ilya Enkovich <ilya.enkovich@intel.com>
+ * dbxout.c (dbxout_type): Ignore POINTER_BOUNDS_TYPE.
+ * dwarf2out.c (gen_subprogram_die): Ignore bound args.
+ (gen_type_die_with_usage): Skip pointer bounds.
+ (dwarf2out_global_decl): Likewise.
+
+ Reverted:
+ 2013-11-18 Ilya Enkovich <ilya.enkovich@intel.com>
+ * builtin-types.def (BT_FN_PTR_CONST_PTR_VAR): New.
+ * chkp-builtins.def (BUILT_IN_CHKP_BIND_BOUNDS): New.
+ * cfgexpand.c (expand_call_stmt): Expand BUILT_IN_CHKP_BIND_BOUNDS.
+ * gimple.c (gimple_call_get_nobnd_arg_index): Remove.
+ * gimple.h (gf_mask): Add GF_CALL_WITH_BOUNDS.
+ (gimple_call_with_bounds_p): New.
+ (gimple_call_set_with_bounds): New.
+ (gimple_call_num_nobnd_args): Remove.
+ (gimple_call_nobnd_arg): Remove.
+ * tree.h (CALL_WITH_BOUNDS_P): New.
+ * rtl.h (CALL_EXPR_WITH_BOUNDS_P): New.
+
+ Reverted:
+ 2013-11-08 Ilya Enkovich <ilya.enkovich@intel.com>
+ * common.opt (fcheck-pointer-bounds): Move to ...
+ * c-family/c.opt: ... here.
+ * langhooks-def.h (LANG_HOOKS_CHKP_SUPPORTED): Remove.
+ (LANG_HOOKS_INITIALIZER): Remove LANG_HOOKS_CHKP_SUPPORTED.
+ * langhooks.h (lang_hooks): Remove chkp_supported field.
+ * toplev.c (process_options): Remove chkp_supported check.
+
+ Reverted:
+ 2013-10-30 Ilya Enkovich <ilya.enkovich@intel.com>
+ * tree-core.h (tree_index): Add TI_POINTER_BOUNDS_TYPE.
+ * tree.h (POINTER_BOUNDS_P): New.
+ (BOUNDED_TYPE_P): New.
+ (BOUNDED_P): New.
+ (pointer_bounds_type_node): New.
+ * tree.c (build_common_tree_nodes): Initialize
+ pointer_bounds_type_node.
+ * gimple.h (gimple_call_get_nobnd_arg_index): New.
+ (gimple_call_num_nobnd_args): New.
+ (gimple_call_nobnd_arg): New.
+ (gimple_return_retbnd): New.
+ (gimple_return_set_retbnd): New
+ * gimple.c (gimple_build_return): Increase number of ops
+ for return statement.
+ (gimple_call_get_nobnd_arg_index): New.
+ * gimple-pretty-print.c (dump_gimple_return): Print second op.
+
+ Reverted:
+ 2013-10-30 Ilya Enkovich <ilya.enkovich@intel.com>
+ * ipa.c (cgraph_build_static_cdtor_1): Support contructors
+ with "chkp ctor" and "bnd_legacy" attributes.
+ * gimplify.c (gimplify_init_constructor): Avoid infinite
+ loop during gimplification of bounds initializer.
+
+ Reverted:
+ 2013-10-30 Ilya Enkovich <ilya.enkovich@intel.com>
+ * c-family/c-common.c (handle_bnd_variable_size_attribute): New.
+ (handle_bnd_legacy): New.
+ (c_common_attribute_table): Add bnd_variable_size and bnd_legacy.
+ * doc/extend.texi: Document bnd_variable_size and bnd_legacy
+ attributes.
+
+ Reverted:
+ 2013-10-29 Ilya Enkovich <ilya.enkovich@intel.com>
+ * builtin-types.def (BT_FN_VOID_CONST_PTR): New.
+ (BT_FN_PTR_CONST_PTR): New.
+ (BT_FN_CONST_PTR_CONST_PTR): New.
+ (BT_FN_PTR_CONST_PTR_SIZE): New.
+ (BT_FN_PTR_CONST_PTR_CONST_PTR): New.
+ (BT_FN_VOID_PTRPTR_CONST_PTR): New.
+ (BT_FN_VOID_CONST_PTR_SIZE): New.
+ (BT_FN_PTR_CONST_PTR_CONST_PTR_SIZE): New.
+ * chkp-builtins.def: New.
+ * builtins.def: include chkp-builtins.def.
+ (DEF_CHKP_BUILTIN): New.
+ * builtins.c (expand_builtin): Support BUILT_IN_CHKP_INIT_PTR_BOUNDS,
+ BUILT_IN_CHKP_NULL_PTR_BOUNDS, BUILT_IN_CHKP_COPY_PTR_BOUNDS,
+ BUILT_IN_CHKP_CHECK_PTR_LBOUNDS, BUILT_IN_CHKP_CHECK_PTR_UBOUNDS,
+ BUILT_IN_CHKP_CHECK_PTR_BOUNDS, BUILT_IN_CHKP_SET_PTR_BOUNDS,
+ BUILT_IN_CHKP_NARROW_PTR_BOUNDS, BUILT_IN_CHKP_STORE_PTR_BOUNDS,
+ BUILT_IN_CHKP_GET_PTR_LBOUND, BUILT_IN_CHKP_GET_PTR_UBOUND,
+ BUILT_IN_CHKP_BNDMK, BUILT_IN_CHKP_BNDSTX, BUILT_IN_CHKP_BNDCL,
+ BUILT_IN_CHKP_BNDCU, BUILT_IN_CHKP_BNDLDX, BUILT_IN_CHKP_BNDRET,
+ BUILT_IN_CHKP_INTERSECT, BUILT_IN_CHKP_ARG_BND, BUILT_IN_CHKP_NARROW,
+ BUILT_IN_CHKP_EXTRACT_LOWER, BUILT_IN_CHKP_EXTRACT_UPPER.
+ * common.opt (fcheck-pointer-bounds): New.
+ * toplev.c (process_options): Check Pointer Bounds Checker is
+ supported.
+ * doc/extend.texi: Document Pointer Bounds Checker built-in functions.
+
+ Reverted:
+ 2013-10-30 Ilya Enkovich <ilya.enkovich@intel.com>
+ * target.def (builtin_chkp_function): New.
+ (chkp_bound_type): New.
+ (chkp_bound_mode): New.
+ (fn_abi_va_list_bounds_size): New.
+ (load_bounds_for_arg): New.
+ (store_bounds_for_arg): New.
+ * targhooks.h (default_load_bounds_for_arg): New.
+ (default_store_bounds_for_arg): New.
+ (default_fn_abi_va_list_bounds_size): New.
+ (default_chkp_bound_type): New.
+ (default_chkp_bound_mode): New.
+ (default_builtin_chkp_function): New.
+ * targhooks.c (default_load_bounds_for_arg): New.
+ (default_store_bounds_for_arg): New.
+ (default_fn_abi_va_list_bounds_size): New.
+ (default_chkp_bound_type): New.
+ (default_chkp_bound_mode); New.
+ (default_builtin_chkp_function): New.
+ * doc/tm.texi.in (TARGET_FN_ABI_VA_LIST_BOUNDS_SIZE): New.
+ (TARGET_LOAD_BOUNDS_FOR_ARG): New.
+ (TARGET_STORE_BOUNDS_FOR_ARG): New.
+ (TARGET_BUILTIN_CHKP_FUNCTION): New.
+ (TARGET_CHKP_BOUND_TYPE): New.
+ (TARGET_CHKP_BOUND_MODE): New.
+ * doc/tm.texi: Regenerated.
+ * langhooks.h (lang_hooks): Add chkp_supported field.
+ * langhooks-def.h (LANG_HOOKS_CHKP_SUPPORTED): New.
+ (LANG_HOOKS_INITIALIZER); Add LANG_HOOKS_CHKP_SUPPORTED.
+
+ Reverted:
+ 2013-10-24 Ilya Enkovich <ilya.enkovich@intel.com>
+ * config/i386/constraints.md (B): New.
+ (Ti): New.
+ (Tb): New.
+ * config/i386/i386-c.c (ix86_target_macros_internal): Add __MPX__.
+ * config/i386/i386-modes.def (BND32): New.
+ (BND64): New.
+ * config/i386/i386-protos.h (ix86_bnd_prefixed_insn_p): New.
+ * config/i386/i386.c (isa_opts): Add mmpx.
+ (regclass_map): Add bound registers.
+ (dbx_register_map): Likewise.
+ (dbx64_register_map): Likewise.
+ (svr4_dbx_register_map): Likewise.
+ (PTA_MPX): New.
+ (ix86_option_override_internal): Support MPX ISA.
+ (ix86_conditional_register_usage): Support bound registers.
+ (print_reg): Likewise.
+ (ix86_code_end): Add MPX bnd prefix.
+ (output_set_got): Likewise.
+ (ix86_output_call_insn): Likewise.
+ (ix86_print_operand): Add '!' (MPX bnd) print prefix support.
+ (ix86_print_operand_punct_valid_p): Likewise.
+ (ix86_print_operand_address): Support UNSPEC_BNDMK_ADDR and
+ UNSPEC_BNDMK_ADDR.
+ (ix86_class_likely_spilled_p): Add bound regs support.
+ (ix86_hard_regno_mode_ok): Likewise.
+ (x86_order_regs_for_local_alloc): Likewise.
+ (ix86_bnd_prefixed_insn_p): New.
+ * config/i386/i386.h (FIRST_PSEUDO_REGISTER): Fix to new value.
+ (FIXED_REGISTERS): Add bound registers.
+ (CALL_USED_REGISTERS): Likewise.
+ (REG_ALLOC_ORDER): Likewise.
+ (HARD_REGNO_NREGS): Likewise.
+ (TARGET_MPX): New.
+ (VALID_BND_REG_MODE): New.
+ (FIRST_BND_REG): New.
+ (LAST_BND_REG): New.
+ (reg_class): Add BND_REGS.
+ (REG_CLASS_NAMES): Likewise.
+ (REG_CLASS_CONTENTS): Likewise.
+ (BND_REGNO_P): New.
+ (ANY_BND_REG_P): New.
+ (BNDmode): New.
+ (HI_REGISTER_NAMES): Add bound registers.
+ * config/i386/i386.md (UNSPEC_BNDMK): New.
+ (UNSPEC_BNDMK_ADDR): New.
+ (UNSPEC_BNDSTX): New.
+ (UNSPEC_BNDLDX): New.
+ (UNSPEC_BNDLDX_ADDR): New.
+ (UNSPEC_BNDCL): New.
+ (UNSPEC_BNDCU): New.
+ (UNSPEC_BNDCN): New.
+ (UNSPEC_MPX_FENCE): New.
+ (BND0_REG): New.
+ (BND1_REG): New.
+ (type): Add mpxmov, mpxmk, mpxchk, mpxld, mpxst.
+ (length_immediate): Likewise.
+ (prefix_0f): Likewise.
+ (memory): Likewise.
+ (prefix_rep): Check for bnd prefix.
+ (length_nobnd): New.
+ (length): Use length_nobnd if specified.
+ (BND): New.
+ (bnd_ptr): New.
+ (BNDCHECK): New.
+ (bndcheck): New.
+ (*jcc_1): Add bnd prefix and rename length attr to length_nobnd.
+ (*jcc_2): Likewise.
+ (jump): Likewise.
+ (simple_return_internal): Likewise.
+ (simple_return_pop_internal): Likewise.
+ (*indirect_jump): Add MPX bnd prefix.
+ (*tablejump_1): Likewise.
+ (simple_return_internal_long): Likewise.
+ (simple_return_indirect_internal): Likewise.
+ (<mode>_mk): New.
+ (*<mode>_mk): New.
+ (mov<mode>): New.
+ (*mov<mode>_internal_mpx): New.
+ (<mode>_<bndcheck>): New.
+ (*<mode>_<bndcheck>): New.
+ (<mode>_ldx): New.
+ (*<mode>_ldx): New.
+ (<mode>_stx): New.
+ (*<mode>_stx): New.
+ * config/i386/predicates.md (lea_address_operand): Rename to...
+ (address_no_seg_operand): ... this.
+ (address_mpx_no_base_operand): New.
+ (address_mpx_no_index_operand): New.
+ (bnd_mem_operator): New.
+ * config/i386/i386.opt (mmpx): New.
+ * doc/invoke.texi: Add documentation for the flags -mmpx, -mno-mpx.
+ * doc/rtl.texi Add documentation for BND32mode and BND64mode.
+
+ Reverted:
+ 2013-10-24 Ilya Enkovich <ilya.enkovich@intel.com>
+ * mode-classes.def (MODE_POINTER_BOUNDS): New.
+ * tree.def (POINTER_BOUNDS_TYPE): New.
+ * genmodes.c (complete_mode): Support MODE_POINTER_BOUNDS.
+ (POINTER_BOUNDS_MODE): New.
+ (make_pointer_bounds_mode): New.
+ * machmode.h (POINTER_BOUNDS_MODE_P): New.
+ * stor-layout.c (int_mode_for_mode): Support MODE_POINTER_BOUNDS.
+ (layout_type): Support POINTER_BOUNDS_TYPE.
+ * tree-pretty-print.c (dump_generic_node): Support POINTER_BOUNDS_TYPE.
+ * tree.c (build_int_cst_wide): Support POINTER_BOUNDS_TYPE.
+ (type_contains_placeholder_1): Likewise.
+ * tree.h (POINTER_BOUNDS_TYPE_P): New.
+ * varasm.c (output_constant): Support POINTER_BOUNDS_TYPE.
+ * doc/rtl.texi (MODE_POINTER_BOUNDS): New.
+
+2013-11-29 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/59338
+ * tree-cfg.c (verify_expr): Restrict bounds verification of
+ BIT_FIELD_REF arguments to non-aggregate typed base objects.
+
+2013-11-29 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/59334
+ * tree-ssa-dce.c (eliminate_unnecessary_stmts): Fix bug
+ in previous commit.
+
+2013-11-29 Jakub Jelinek <jakub@redhat.com>
+ Richard Biener <rguenther@suse.de>
+
+ PR lto/59326
+ * omp-low.c (simd_clone_create): Return NULL if for definition
+ !cgraph_function_with_gimple_body_p (old_node). Call cgraph_get_body
+ before calling cgraph_function_versioning.
+ (expand_simd_clones): Look for "omp declare simd" attribute first.
+ Don't check targetm.simd_clone.compute_vecsize_and_simdlen here.
+ Punt if node->global.inlined_to.
+ (pass_omp_simd_clone::gate): Also enable if in_lto_p && !flag_wpa.
+ Disable pass if targetm.simd_clone.compute_vecsize_and_simdlen is NULL.
+ * lto-streamer-out.c (hash_tree): Handle OMP_CLAUSE.
+
+2013-11-29 Jakub Jelinek <jakub@redhat.com>
+
+ PR lto/59326
+ * tree-core.h (enum omp_clause_schedule_kind): Add
+ OMP_CLAUSE_SCHEDULE_LAST.
+ (enum omp_clause_default_kind): Add OMP_CLAUSE_DEFAULT_LAST.
+ (enum omp_clause_depend_kind): Add OMP_CLAUSE_DEPEND_LAST.
+ (enum omp_clause_map_kind): Add OMP_CLAUSE_MAP_LAST.
+ (enum omp_clause_proc_bind_kind): Add OMP_CLAUSE_PROC_BIND_LAST.
+ * lto-streamer-out.c (lto_is_streamable): Allow streaming
+ OMP_CLAUSE.
+ (DFS_write_tree_body): Handle OMP_CLAUSE.
+ * tree-streamer-out.c (pack_ts_omp_clause_value_fields): New
+ function.
+ (streamer_pack_tree_bitfields): Call it for OMP_CLAUSE.
+ (write_ts_omp_clause_tree_pointers): New function.
+ (streamer_write_tree_body): Call it for OMP_CLAUSE.
+ (streamer_write_tree_header): For OMP_CLAUSE stream OMP_CLAUSE_CODE.
+ * tree-streamer-in.c (unpack_ts_omp_clause_value_fields): New
+ function.
+ (unpack_value_fields): Call it for OMP_CLAUSE.
+ (streamer_alloc_tree): Handle OMP_CLAUSE.
+ (lto_input_ts_omp_clause_tree_pointers): New function.
+ (streamer_read_tree_body): Call it for OMP_CLAUSE.
+
+2013-11-29 Joseph Myers <joseph@codesourcery.com>
+
+ * doc/implement-c.texi: Document C11 implementation-defined
+ behavior. Refer to -ffp-contract=fast for contraction behavior.
+ * doc/invoke.texi (-std=c99, std=c11): Update description of
+ completeness.
+ (-std=gnu99): Don't mention as future default.
+ (-std=gnu11): Mention as intended future default.
+ * doc/standards.texi: Update descriptions of C99 and C11 support.
+ Limit statement about C99 facilities for freestanding
+ implementations to some platforms only.
+
+2013-11-28 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/59327
+ * cfgexpand.c (expand_used_vars): Avoid warning on 32-bit
+ HWI hosts.
+
+2013-11-28 Vladimir Makarov <vmakarov@redhat.com>
+
+ PR target/57293
+ * ira.h (ira_setup_eliminable_regset): Remove parameter.
+ * ira.c (ira_setup_eliminable_regset): Ditto. Add
+ SUPPORTS_STACK_ALIGNMENT for crtl->stack_realign_needed.
+ Don't call lra_init_elimination.
+ (ira): Call ira_setup_eliminable_regset without arguments.
+ * loop-invariant.c (calculate_loop_reg_pressure): Remove argument
+ from ira_setup_eliminable_regset call.
+ * gcse.c (calculate_bb_reg_pressure): Ditto.
+ * haifa-sched.c (sched_init): Ditto.
+ * lra.h (lra_init_elimination): Remove the prototype.
+ * lra-int.h (lra_insn_recog_data): New member sp_offset. Move
+ used_insn_alternative upper.
+ (lra_eliminate_regs_1): Add one more parameter.
+ (lra-eliminate): Ditto.
+ * lra.c (lra_invalidate_insn_data): Set sp_offset.
+ (setup_sp_offset): New.
+ (lra_process_new_insns): Call setup_sp_offset.
+ (lra): Add argument to lra_eliminate calls.
+ * lra-constraints.c (get_equiv_substitution): Rename to get_equiv.
+ (get_equiv_with_elimination): New.
+ (process_addr_reg): Call get_equiv_with_elimination instead of
+ get_equiv_substitution.
+ (equiv_address_substitution): Ditto.
+ (loc_equivalence_change_p): Ditto.
+ (loc_equivalence_callback, lra_constraints): Ditto.
+ (curr_insn_transform): Ditto. Print the sp offset
+ (process_alt_operands): Prevent stack pointer reloads.
+ (lra_constraints): Remove one argument from lra_eliminate call.
+ Move it up. Mark used hard regs bfore it. Use
+ get_equiv_with_elimination instead of get_equiv_substitution.
+ * lra-eliminations.c (lra_eliminate_regs_1): Add parameter and
+ assert for param values combination. Use sp offset. Add argument
+ to lra_eliminate_regs_1 calls.
+ (lra_eliminate_regs): Add argument to lra_eliminate_regs_1 call.
+ (curr_sp_change): New static var.
+ (mark_not_eliminable): Add parameter. Update curr_sp_change.
+ Don't prevent elimination to sp if we can calculate its change.
+ Pass the argument to mark_not_eliminable calls.
+ (eliminate_regs_in_insn): Add a parameter. Use sp offset. Add
+ argument to lra_eliminate_regs_1 call.
+ (update_reg_eliminate): Move calculation of hard regs for spill
+ lower. Switch off lra_in_progress temporarily to generate regs
+ involved into elimination.
+ (lra_init_elimination): Rename to init_elimination. Make it
+ static. Set up insn sp offset, check the offsets at the end of
+ BBs.
+ (process_insn_for_elimination): Add parameter. Pass its value to
+ eliminate_regs_in_insn.
+ (lra_eliminate): : Add parameter. Pass its value to
+ process_insn_for_elimination. Add assert for param values
+ combination. Call init_elimination. Don't update offsets in
+ equivalence substitutions.
+ * lra-spills.c (assign_mem_slot): Don't call lra_eliminate_regs_1
+ for created stack slot.
+ (remove_pseudos): Call lra_eliminate_regs_1 before changing memory
+ onto stack slot.
+
+2013-11-28 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * config/arm/iterators.md (vrint_conds): New int attribute.
+ * config/arm/vfp.md (<vrint_pattern><SDF:mode>2): Set conds attribute.
+ (smax<mode>3): Likewise.
+ (smin<mode>3): Likewise.
+
+2013-11-28 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * tree-core.h (tree_base): Document use of static_flag for SSA_NAME.
+ * tree.h (SSA_NAME_ANTI_RANGE_P, SSA_NAME_RANGE_TYPE): New macros.
+ * tree-ssanames.h (set_range_info): Add range_type argument.
+ (duplicate_ssa_name_range_info): Likewise.
+ * tree-ssanames.c (set_range_info): Take the range type as argument
+ and store it in SSA_NAME_ANTI_RANGE_P.
+ (duplicate_ssa_name_range_info): Likewise.
+ (get_range_info): Use SSA_NAME_ANTI_RANGE_P.
+ (set_nonzero_bits): Update call to set_range_info.
+ (duplicate_ssa_name_fn): Update call to duplicate_ssa_name_range_info.
+ * tree-ssa-copy.c (fini_copy_prop): Likewise.
+ * tree-vrp.c (remove_range_assertions): Update call to set_range_info.
+ (vrp_finalize): Likewise, passing anti-ranges directly.
+
+2013-11-28 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/59330
+ * tree-ssa-dce.c (eliminate_unnecessary_stmts): Simplify
+ and fix delayed marking of free calls not necessary.
+
+2013-11-28 Andrew MacLeod <amacleod@redhat.com>
+
+ * tree-ssa-propagate.c (valid_gimple_call_p): Pass TREE_TYPE to
+ is_gimple_reg_type.
+ * ipa-prop.c (determine_known_aggregate_parts): Likewise.
+
+2013-11-28 Terry Guo <terry.guo@arm.com>
+
+ * config/arm/arm.c (v7m_extra_costs): New table.
+ (arm_v7m_tune): Use it.
+
+2013-11-28 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ * config/sol2.h (TIME_LIBRARY): Define.
+
+2013-11-28 Richard Biener <rguenther@suse.de>
+
+ PR lto/59323
+ * lto-streamer-out.c (tree_is_indexable): TYPE_DECLs and
+ CONST_DECLs in function context are not indexable.
+
+2013-11-28 Chung-Ju Wu <jasonwucj@gmail.com>
+
+ * config/nds32/nds32.c (nds32_rtx_costs): Adjust MULT cost if it is
+ not optimized for size.
+
+2013-11-28 Jakub Jelinek <jakub@redhat.com>
+
+ * cfgexpand.c (struct stack_vars_data): Add asan_base and asan_alignb
+ fields.
+ (expand_stack_vars): For -fsanitize=address, use (and set initially)
+ data->asan_base as base for vars and update asan_alignb.
+ (expand_used_vars): Initialize data.asan_base and data.asan_alignb.
+ Pass them to asan_emit_stack_protection.
+ * asan.c (asan_detect_stack_use_after_return): New variable.
+ (asan_emit_stack_protection): Add pbase and alignb arguments.
+ Implement use after return sanitization.
+ * asan.h (asan_emit_stack_protection): Adjust prototype.
+ (ASAN_STACK_MAGIC_USE_AFTER_RET, ASAN_STACK_RETIRED_MAGIC): Define.
+
+2013-11-28 Sergey Ostanevich <sergos.gnu@gmail.com>
+
+ * common.opt: Introduced a new option -fsimd-cost-model.
+ * doc/invoke.texi: Introduced a new openmp-simd warning and
+ a new -fsimd-cost-model option.
+ * tree-vectorizer.h (unlimited_cost_model): Interface updated
+ to rely on the particular loop info.
+ * tree-vect-data-refs.c (vect_peeling_hash_insert): Ditto.
+ (vect_peeling_hash_choose_best_peeling): Ditto.
+ (vect_enhance_data_refs_alignment): Ditto.
+ * tree-vect-slp.c (vect_slp_analyze_bb_1): Ditto.
+ * tree-vect-loop.c (vect_estimate_min_profitable_iters): Ditto
+ plus added openmp-simd warining.
+
+2013-11-27 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR rtl-optimization/59311
+ * dwarf2cfi.c (dwf_regno): Assert reg isn't pseudo register.
+ * lra-spills.c (spill_pseudos): Handle REG_XXX notes.
+
+2013-11-27 Eric Botcazou <ebotcazou@adacore.com>
+
+ * var-tracking.c (track_expr_p): Do not track declarations for parts
+ of tracked parameters.
+ (add_stores): Do not track values for tracked parameters passed in
+ multiple locations.
+ (vt_get_decl_and_offset): Handle PARALLEL.
+ (vt_add_function_parameter): Handle parameters with incoming PARALLEL.
+
+2013-11-27 Jeff Law <law@redhat.com>
+
+ * tree-ssa-threadupdate.c (thread_through_all_blocks): Do not
+ clobber the loop structure thread_block was unsuccessful. If
+ thread_block was unsuccessful, cleanup appropriately.
+
+2013-11-27 Chen Liqin <liqin.gcc@gmail.com>
+
+ * config/score/score.h (REG_CLASS_FROM_LETTER): Delete.
+ (score_char_to_class): Likewise.
+
+2013-11-27 Kenneth Zadeck <zadeck@naturalbridge.com>
+
+ * fold-const.c (int_const_binop_1): Make INT_MIN % -1 return 0 with the
+ overflow bit set.
+
+2013-11-27 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/58723
+ * cgraphbuild.c (build_cgraph_edges): Do not build edges
+ for internal calls.
+ (rebuild_cgraph_edges): Likewise.
+ * ipa-inline-analysis.c (estimate_function_body_sizes):
+ Skip internal calls.
+ * tree-inline.c (estimate_num_insns): Estimate size of internal
+ calls as 0.
+ (gimple_expand_calls_inline): Do not try inline-expanding
+ internal calls.
+ * lto-streamer-in.c (input_cfg): Stream loop safelen,
+ force_vect and simduid.
+ (input_struct_function_base): Stream has_force_vect_loops
+ and has_simduid_loops.
+ (input_function): Adjust.
+ * lto-streamer-out.c (output_cfg): Stream loop safelen,
+ force_vect and simduid.
+ (output_struct_function_base): Stream has_force_vect_loops
+ and has_simduid_loops.
+
+2013-11-27 Kai Tietz <ktietz@redhat.com>
+
+ * config/i386/winnt.c (i386_pe_section_type_flags): Use const
+ pointer cast.
+
+2013-11-27 Kugan Vivekanandarajah <kuganv@linaro.org>
+
+ * doc/tm.texi.in (TARGET_HAS_NO_HW_DIVIDE): Define.
+ * doc/tm.texi (TARGET_HAS_NO_HW_DIVIDE): Regenerate.
+
+2013-11-27 Marek Polacek <polacek@redhat.com>
+
+ PR sanitizer/59306
+ * ubsan.c (instrument_null): Use gimple_store_p/gimple_assign_load_p
+ instead of walk_gimple_op.
+ (ubsan_pass): Adjust. Call instrument_null only if SANITIZE_NULL.
+
+2013-11-27 Aldy Hernandez <aldyh@redhat.com>
+ Jakub Jelinek <jakub@redhat.com>
+
+ * cgraph.h (enum cgraph_simd_clone_arg_type): New.
+ (struct cgraph_simd_clone_arg, struct cgraph_simd_clone): New.
+ (struct cgraph_node): Add simdclone and simd_clones fields.
+ * config/i386/i386.c (ix86_simd_clone_compute_vecsize_and_simdlen,
+ ix86_simd_clone_adjust, ix86_simd_clone_usable): New functions.
+ (TARGET_SIMD_CLONE_COMPUTE_VECSIZE_AND_SIMDLEN,
+ TARGET_SIMD_CLONE_ADJUST, TARGET_SIMD_CLONE_USABLE): Define.
+ * doc/tm.texi.in (TARGET_SIMD_CLONE_COMPUTE_VECSIZE_AND_SIMDLEN,
+ TARGET_SIMD_CLONE_ADJUST, TARGET_SIMD_CLONE_USABLE): Add.
+ * doc/tm.texi: Regenerated.
+ * ggc.h (ggc_alloc_cleared_simd_clone_stat): New function.
+ * ipa-cp.c (determine_versionability): Fail if "omp declare simd"
+ attribute is present.
+ * omp-low.c: Include pretty-print.h, ipa-prop.h and tree-eh.h.
+ (simd_clone_vector_of_formal_parm_types): New function.
+ (simd_clone_struct_alloc, simd_clone_struct_copy,
+ simd_clone_vector_of_formal_parm_types, simd_clone_clauses_extract,
+ simd_clone_compute_base_data_type, simd_clone_mangle,
+ simd_clone_create, simd_clone_adjust_return_type,
+ create_tmp_simd_array, simd_clone_adjust_argument_types,
+ simd_clone_init_simd_arrays): New functions.
+ (struct modify_stmt_info): New type.
+ (ipa_simd_modify_stmt_ops, ipa_simd_modify_function_body,
+ simd_clone_adjust, expand_simd_clones, ipa_omp_simd_clone): New
+ functions.
+ (pass_data_omp_simd_clone): New variable.
+ (pass_omp_simd_clone): New class.
+ (make_pass_omp_simd_clone): New function.
+ * passes.def (pass_omp_simd_clone): New.
+ * target.def (TARGET_SIMD_CLONE_COMPUTE_VECSIZE_AND_SIMDLEN,
+ TARGET_SIMD_CLONE_ADJUST, TARGET_SIMD_CLONE_USABLE): New target
+ hooks.
+ * target.h (struct cgraph_node, struct cgraph_simd_node): Declare.
+ * tree-core.h (OMP_CLAUSE_LINEAR_VARIABLE_STRIDE): Document.
+ * tree.h (OMP_CLAUSE_LINEAR_VARIABLE_STRIDE): Define.
+ * tree-pass.h (make_pass_omp_simd_clone): New prototype.
+ * tree-vect-data-refs.c: Include cgraph.h.
+ (vect_analyze_data_refs): Inline by hand find_data_references_in_loop
+ and find_data_references_in_bb, if find_data_references_in_stmt
+ fails, still allow calls to #pragma omp declare simd functions
+ in #pragma omp simd loops unless they contain data references among
+ the call arguments or in lhs.
+ * tree-vect-loop.c (vect_determine_vectorization_factor): Handle
+ calls with no lhs.
+ (vect_transform_loop): Allow NULL STMT_VINFO_VECTYPE for calls without
+ lhs.
+ * tree-vectorizer.h (enum stmt_vec_info_type): Add
+ call_simd_clone_vec_info_type.
+ (struct _stmt_vec_info): Add simd_clone_fndecl field.
+ (STMT_VINFO_SIMD_CLONE_FNDECL): Define.
+ * tree-vect-stmts.c: Include tree-ssa-loop.h,
+ tree-scalar-evolution.h and cgraph.h.
+ (vectorizable_call): Handle calls without lhs. Assert
+ !stmt_can_throw_internal instead of failing for it. Don't update
+ EH stuff.
+ (struct simd_call_arg_info): New.
+ (vectorizable_simd_clone_call): New function.
+ (vect_transform_stmt): Call it.
+ (vect_analyze_stmt): Likewise. Allow NULL STMT_VINFO_VECTYPE for
+ calls without lhs.
+ * ipa-prop.c (ipa_add_new_function): Only call ipa_analyze_node
+ if cgraph_function_with_gimple_body_p is true.
+
+2013-11-27 Tom de Vries <tom@codesourcery.com>
+ Marc Glisse <marc.glisse@inria.fr>
+
+ PR middle-end/59037
+ * fold-const.c (fold_indirect_ref_1): Don't create out-of-bounds
+ BIT_FIELD_REF.
+ * gimple-fold.c (gimple_fold_indirect_ref): Same.
+ * tree-cfg.c (verify_expr): Give error if BIT_FIELD_REF is
+ out-of-bounds.
+
+2013-11-27 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR middle-end/59138
+ * expr.c (emit_group_store): Don't write past the end of the structure.
+ (store_bit_field): Fix formatting.
+
+2013-11-27 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/59288
+ * tree-vect-loop.c (get_initial_def_for_induction): Do not
+ re-analyze the PHI but use STMT_VINFO_LOOP_PHI_EVOLUTION_PART.
+
+2013-11-27 Marek Polacek <polacek@redhat.com>
+
+ * ubsan.c (ubsan_type_descriptor): If varpool_get_node returns NULL
+ for a decl, recreate that decl. Save into the hash table VAR_DECLs
+ rather than ADDR_EXPRs.
+
+2013-11-27 Alexander Ivchenko <alexander.ivchenko@intel.com>
+
+ * config/ia64/hpux.h (TARGET_LIBC_HAS_FUNCTION): Fix typo.
+
+2013-11-26 David Malcolm <dmalcolm@redhat.com>
+
+ * gengtype.c (struct seen_tag): New.
+ (already_seen_tag): New.
+ (mark_tag_as_seen): New.
+ (walk_subclasses): Support having multiple subclasses using the
+ same tag by tracking which tags have already been seen, and using
+ this to avoid adding duplicate cases to the "switch" statement.
+ The call to already_seen_tag introduces an O(N^2) when running
+ gengtype on N, the number of tags, due to the repeated linear
+ search, but currently max(N) is relatively small (the number of
+ GSS codes, which is 26).
+ (walk_type): Pass in a seen_tag for use by the walk_subclasses
+ recursion.
+
+ * gimple.def (GIMPLE_OMP_ATOMIC_STORE, GIMPLE_OMP_RETURN): Rename
+ underlying GSS values for these codes (from GSS_OMP_ATOMIC_STORE to
+ GSS_OMP_ATOMIC_STORE_LAYOUT) to make clear that although
+ GIMPLE_OMP_RETURN happens to share the data layout of
+ GIMPLE_OMP_ATOMIC_STORE, they are not otherwise related.
+ (GIMPLE_OMP_PARALLEL, GIMPLE_OMP_TARGET): Likewise, rename
+ underlying GSS value from GSS_OMP_PARALLEL to
+ GSS_OMP_PARALLEL_LAYOUT to make clear that these gimple codes are
+ not directly related; they merely share in-memory layout.
+ (GIMPLE_OMP_SINGLE, GIMPLE_OMP_TEAMS): Likewise, rename GSS values
+ for these two codes from GSS_OMP_SINGLE to GSS_OMP_SINGLE_LAYOUT.
+
+ * gsstruct.def (GSS_OMP_PARALLEL, gimple_statement_omp_parallel):
+ Rename to...
+ (GSS_OMP_PARALLEL_LAYOUT, gimple_statement_omp_parallel_layout):
+ ...these.
+ (GSS_OMP_SINGLE, gimple_statement_omp_single): Rename to...
+ (GSS_OMP_SINGLE_LAYOUT, gimple_statement_omp_single_layout):
+ ...these.
+ (GSS_OMP_ATOMIC_STORE, gimple_statement_omp_atomic_store): Rename
+ to...
+ (GSS_OMP_ATOMIC_STORE_LAYOUT, gimple_statement_omp_atomic_store):
+ ...these.
+
+ * gimple.h (gimple_statement_resx): New subclass of
+ gimple_statement_eh_ctrl, with the invariant that
+ stmt->code == GIMPLE_RESX.
+ (gimple_statement_eh_dispatch): New subclass of
+ gimple_statement_eh_ctrl, with the invariant that
+ stmt->code == GIMPLE_EH_DISPATH.
+
+ (gimple_statement_omp_parallel): The existing class expressed
+ a layout (GSS_OMP_PARALLEL), but the codes with that layout
+ are not all related, so it makes more sense for this class to
+ express a *code* (GIMPLE_OMP_PARALLEL). GSS_OMP_PARALLEL has
+ been renamed to GSS_OMP_PARALLEL_LAYOUT to express this, so
+ rename the existing gimple_statement_omp_parallel class to...
+ (gimple_statement_omp_parallel_layout): ...this, expressing
+ a statement of structure layout GSS_OMP_PARALLEL_LAYOUT.
+ (gimple_statement_omp_taskreg): New subclass of
+ gimple_statement_omp_parallel_layout, expressing the invariant
+ that the code is one of GIMPLE_OMP_PARALLEL or GIMPLE_OMP_TASK,
+ as used by the various gimple_omp_taskreg_ accessors.
+ (gimple_statement_omp_parallel): Reintroduce this class, this time
+ as a subclass of gimple_statement_omp_taskreg to express the
+ invariant stmt->code == GIMPLE_OMP_PARALLEL.
+ (gimple_statement_omp_target) New class, subclassing
+ gimple_statement_omp_parallel_layout, to express the invariant
+ stmt->code == GIMPLE_OMP_TARGET.
+ (gimple_statement_omp_task): Update to inherit from
+ gimple_statement_omp_taskreg rather than
+ gimple_statement_omp_parallel.
+
+ (gimple_statement_omp_single): Rename to...
+ (gimple_statement_omp_single_layout): ...this, expressing the
+ invariant that the layout is GSS_OMP_SINGLE_LAYOUT.
+ (gimple_statement_omp_single): ...and reintroduce this name as
+ a subclass of gimple_statement_omp_single_layout, expressing
+ the invariant that code == GIMPLE_OMP_SINGLE.
+ (gimple_statement_omp_teams): New class, subclassing
+ gimple_statement_omp_single_layout, for the code GIMPLE_OMP_TEAMS.
+
+ (gimple_statement_omp_atomic_store): Rename to...
+ (gimple_statement_omp_atomic_store_layout): ...this, expressing
+ the invariant that the layout is GSS_OMP_ATOMIC_STORE_LAYOUT.
+ (gimple_statement_omp_atomic_store): ...and reintroduce this
+ name as a subclass of gimple_statement_omp_atomic_store_layout
+ with code == GIMPLE_OMP_ATOMIC_STORE.
+ (gimple_statement_omp_return): New class, subclassing
+ gimple_statement_omp_atomic_store_layout for the code
+ GIMPLE_OMP_RETURN.
+
+ (is_a_helper <gimple_statement_eh_ctrl>::test): Delete.
+ (is_a_helper <gimple_statement_resx>::test): New.
+ (is_a_helper <gimple_statement_eh_dispatch>::test): New.
+ (is_a_helper <gimple_statement_omp_atomic_store>::test): Only
+ check for GIMPLE_OMP_ATOMIC_STORE, not for GIMPLE_OMP_RETURN.
+ (is_a_helper <gimple_statement_omp_return>::test): New.
+ (is_a_helper <gimple_statement_omp_taskreg>::test): New.
+ (is_a_helper <gimple_statement_omp_parallel>::test): Only check
+ for GIMPLE_OMP_PARALLEL, not for GIMPLE_OMP_TASK or
+ GIMPLE_OMP_TARGET.
+ (is_a_helper <gimple_statement_omp_target>::test): New.
+ (is_a_helper <gimple_statement_omp_single>::test): Only check
+ for GIMPLE_OMP_SINGLE, not for GIMPLE_OMP_TEAMS.
+ (is_a_helper <gimple_statement_omp_teams>::test): New.
+
+ (is_a_helper <const gimple_statement_eh_ctrl>::test): Delete.
+ (is_a_helper <const gimple_statement_resx>::test): New.
+ (is_a_helper <const gimple_statement_eh_dispatch>::test): New.
+ (is_a_helper <const gimple_statement_omp_atomic_store>::test): Only
+ check for GIMPLE_OMP_ATOMIC_STORE, not for GIMPLE_OMP_RETURN.
+ (is_a_helper <const gimple_statement_omp_return>::test): New.
+ (is_a_helper <const gimple_statement_omp_taskreg>::test): New.
+ (is_a_helper <const gimple_statement_omp_parallel>::test): Only
+ check for GIMPLE_OMP_PARALLEL, not for GIMPLE_OMP_TASK or
+ GIMPLE_OMP_TARGET.
+ (is_a_helper <const gimple_statement_omp_target>::test): New.
+ (is_a_helper <const gimple_statement_omp_single>::test): Only
+ check for GIMPLE_OMP_SINGLE, not for GIMPLE_OMP_TEAMS.
+ (is_a_helper <const gimple_statement_omp_teams>::test): New.
+
+ (gimple_omp_return_set_lhs, gimple_omp_return_lhs,
+ gimple_omp_return_lhs_ptr): Replace bogus downcasts to
+ gimple_statement_omp_atomic_store with downcasts to
+ gimple_statement_omp_return, thus requiring that the code be
+ GIMPLE_OMP_RETURN.
+ (gimple_resx_region, gimple_resx_set_region): Replace bogus
+ downcasts to gimple_statement_eh_ctrl with downcasts to
+ gimple_statement_resx, thus requiring that the code be
+ GIMPLE_RESX.
+ (gimple_eh_dispatch_region, gimple_eh_dispatch_set_region):
+ Replace bogus downcasts to const gimple_statement_eh_ctrl with
+ downcasts to gimple_statement_eh_dispatch, thus requiring that
+ the code be GIMPLE_EH_DISPATCH.
+ (gimple_omp_taskreg_clauses, gimple_omp_taskreg_clauses_ptr)
+ gimple_omp_taskreg_set_clauses, gimple_omp_taskreg_child_fn,
+ gimple_omp_taskreg_child_fn_ptr, gimple_omp_taskreg_set_child_fn,
+ gimple_omp_taskreg_data_arg, gimple_omp_taskreg_data_arg_ptr,
+ gimple_omp_taskreg_set_data_arg): Replace bogus downcasts to
+ gimple_statement_omp_parallel with downcasts to
+ gimple_statement_omp_taskreg, thus requiring that the code be
+ either GIMPLE_OMP_PARALLEL or GIMPLE_OMP_TASK.
+ (gimple_omp_target_clauses, gimple_omp_target_clauses_ptr
+ gimple_omp_target_set_clauses, gimple_omp_target_child_fn
+ gimple_omp_target_child_fn_ptr, gimple_omp_target_set_child_fn
+ gimple_omp_target_data_arg, gimple_omp_target_data_arg_ptr
+ gimple_omp_target_set_data_arg): Replace bogus downcasts to
+ gimple_statement_omp_parallel with downcasts to
+ gimple_statement_omp_target, thus requiring that the code be
+ GIMPLE_OMP_TARGET.
+ (gimple_omp_teams_clauses, gimple_omp_teams_clauses_ptr
+ gimple_omp_teams_set_clauses): Replace bogus downcasts to
+ gimple_statement_omp_single with downcasts to
+ gimple_statement_omp_teams, thus requiring that the code be
+ GIMPLE_OMP_TEAMS.
+
+ * gimple.c (gimple_build_resx): Fix bogus as_a<> to use
+ gimple_statement_resx.
+ (gimple_build_eh_dispatch): Fix bogus as_a<> to use
+ gimple_statement_eh_dispatch.
+
+2013-11-26 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/59014
+ * tree-vrp.c (register_edge_assert_for_1): Don't look
+ through conversions from non-integral types or through
+ narrowing conversions.
+
+ PR target/59229
+ * config/i386/i386.c (device_alg): Fix up formatting.
+ (ix86_expand_set_or_movmem): Handle max_size < epilogue_size_needed
+ similarly to count && count < epilogue_size_needed. Fix up
+ comment typo.
+ * builtins.c (determine_block_size): Fix comment typo.
+
+ PR sanitizer/59258
+ * ubsan.c (ubsan_source_location): Don't add any location
+ to ADDR_EXPR in the ctor. Revert 2013-11-22 change.
+ (ubsan_create_data): Strip block info from LOC.
+
+ PR middle-end/59273
+ * tree-vect-generic.c (optimize_vector_constructor): Don't optimize
+ if there isn't optab handler for the corresponding vector PLUS_EXPR.
+
+ PR rtl-optimization/59166
+ * ira.c (find_moveable_pseudos): Use DF_REF_REAL_LOC instead of
+ DF_REF_LOC in validate_change call.
+ (split_live_ranges_for_shrink_wrap): Likewise.
+
+ PR middle-end/59150
+ * omp-low.c (lower_rec_input_clause): For reduction with placeholder
+ of references to constant size types in simd loops, defer emitting
+ initializer for the new_var, emit it later on only if not using
+ SIMD arrays for it.
+
+ PR middle-end/59152
+ * omp-low.c (expand_omp_for_static_chunk): Don't set loop->latch
+ for the inner loop if collapse_bb is non-NULL.
+ (expand_omp_simd): Use cont_bb rather than e->dest as latch.
+
+2013-11-26 Yufeng Zhang <yufeng.zhang@arm.com>
+
+ * config/arm/arm.c (arm_legitimize_address): Check xop1 is not
+ a constant immediate before force_reg.
+
+2013-11-26 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/59245
+ * tree-vrp.c (set_value_range): Assert that we don't have
+ overflowed constants (but our infinities).
+ (set_value_range_to_value): Drop all overflow flags.
+ (vrp_visit_phi_node): Likewise.
+ (vrp_visit_assignment_or_call): Use set_value_range_to_value
+ to set a constant range.
+
+2013-11-26 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ PR target/59290
+ * config/arm/arm.md (*zextendsidi_negsi): New pattern.
+ * config/arm/arm.c (arm_new_rtx_costs): Initialise cost correctly
+ for zero_extend case.
+
+2013-11-26 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR bootstrap/55552
+ * configure.ac (install_gold_as_default): New. Set to yes for
+ --disable-ld or --enable-gold=default.
+ (gcc_cv_ld_gold_srcdir): New.
+ (gcc_cv_ld): Also check in-tree gold if install_gold_as_default
+ is yes.
+ (ORIGINAL_LD_BFD_FOR_TARGET): New AC_SUBST.
+ (ORIGINAL_LD_GOLD_FOR_TARGET): Likewise.
+ * configure: Regenerated.
+
+ * exec-tool.in (ORIGINAL_LD_BFD_FOR_TARGET): New variable.
+ (ORIGINAL_LD_GOLD_FOR_TARGET): Likewise.
+ (original) [collect-ld && -fuse-ld=bfd]: Set to
+ $ORIGINAL_LD_BFD_FOR_TARGET.
+ (original) [collect-ld && -fuse-ld=gold]: Set to
+ $ORIGINAL_LD_GOLD_FOR_TARGET.
+ (dir) [collect-ld && ../gold/ld-new]: Set to gold.
+ (fast_install) [collect-ld && ../gold/ld-new]: Set to yes.
+
+2013-11-26 Terry Guo <terry.guo@arm.com>
+
+ * config/arm/arm.c (require_pic_register): Handle high pic base
+ register for thumb-1.
+ (arm_load_pic_register): Also initialize high pic base register.
+ * doc/invoke.texi: Update documentation for option -mpic-register.
+
+2013-11-26 Oleg Endo <olegendo@gcc.gnu.org>
+
+ PR target/58314
+ PR target/50751
+ * config/sh/sh.c (max_mov_insn_displacement, disp_addr_displacement):
+ Prefix function names with 'sh_'. Make them non-static.
+ * config/sh/sh-protos.h (sh_disp_addr_displacement,
+ sh_max_mov_insn_displacement): Add declarations.
+ * config/sh/constraints.md (Q): Reject QImode.
+ (Sdd): Use match_code "mem".
+ (Snd): Fix erroneous matching of non-memory operands.
+ * config/sh/predicates.md (short_displacement_mem_operand): New
+ predicate.
+ (general_movsrc_operand): Disallow PC relative QImode loads.
+ * config/sh/sh.md (*mov<mode>_reg_reg): Remove it.
+ (*movqi, *movhi): Merge both insns into...
+ (*mov<mode>): ... this new insn. Replace generic 'm' constraints with
+ 'Snd' and 'Sdd' constraints. Calculate insn length dynamically based
+ on the operand types.
+
+2013-11-26 Joern Rennecke <joern.rennecke@embecosm.com>
+
+ * config/epiphany/epiphany.c (epiphany_expand_prologue):
+ Remove unused variable save_config.
+ (epiphany_compute_frame_size): Avoid signed/unsigned comparison in
+ assert.
+
+2013-11-26 James Greenhalgh <james.greenhalgh@arm.com>
+
+ * config/aarch64/arm_neon.h (vtbx1_<psu>8): Emulate behaviour
+ using other intrinsics.
+ (vtbx3_<psu>8): Likewise.
+
+2013-11-26 James Greenhalgh <james.greenhalgh@arm.com>
+
+ * config/aarch64/aarch64-builtins.c
+ (aarch64_types_bsl_p_qualifiers): New.
+ (aarch64_types_bsl_s_qualifiers): Likewise.
+ (aarch64_types_bsl_u_qualifiers): Likewise.
+ (TYPES_BSL_P): Likewise.
+ (TYPES_BSL_S): Likewise.
+ (TYPES_BSL_U): Likewise.
+ (BUILTIN_VALLDIF): Likewise.
+ (BUILTIN_VDQQH): Likewise.
+ * config/aarch64/aarch64-simd-builtins.def (simd_bsl): New.
+ * config/aarch64/aarch64-simd.md
+ (aarch64_simd_bsl<mode>_internal): Handle more modes.
+ (aarch64_simd_bsl<mode>): Likewise.
+ * config/aarch64/arm_neon.h
+ (vbsl<q>_<fpsu><8,16,32,64): Implement using builtins.
+ * config/aarch64/iterators.md (VALLDIF): New.
+ (Vbtype): Handle more modes.
+
+2013-11-26 James Greenhalgh <james.greenhalgh@arm.com>
+
+ * config/aarch64/aarch64-builtins.c
+ (aarch64_type_qualifiers): Add qualifier_poly.
+ (aarch64_build_scalar_type): Also build Poly types.
+ (aarch64_build_vector_type): Likewise.
+ (aarch64_build_type): Likewise.
+ (aarch64_build_signed_type): New.
+ (aarch64_build_unsigned_type): Likewise.
+ (aarch64_build_poly_type): Likewise.
+ (aarch64_init_simd_builtins): Also handle Poly types.
+
+2013-11-26 James Greenhalgh <james.greenhalgh@arm.com>
+
+ * config/aarch64/aarch64-builtins.c
+ (VAR1): Use new naming scheme for aarch64_builtins.
+ (aarch64_builtin_vectorized_function): Use new
+ aarch64_builtins names.
+
+2013-11-26 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/59287
+ * tree-ssa-structalias.c (get_constraint_for_component_ref):
+ Remove no longer necessary special-casing of union accesses.
+
+2013-11-26 Richard Biener <rguenther@suse.de>
+
+ * pretty-print.c (output_buffer::~output_buffer): Really
+ free the obstacks.
+
+2013-11-25 Jeff Law <law@redhat.com>
+
+ * tree-ssa-threadupdate.c (thread_through_all_blocks): Selectively
+ invalidate loop information.
+
+2013-11-25 Oleg Endo <olegendo@gcc.gnu.org>
+
+ * config/sh/sh.md (doloop_end_split): Add missing SI mode.
+
+2013-11-25 Oleg Endo <olegendo@gcc.gnu.org>
+
+ PR target/53976
+ PR target/59243
+ * config/sh/sh_optimize_sett_clrt.cc (struct ccreg_value): Update
+ comments.
+ (sh_optimize_sett_clrt::find_last_ccreg_values): Check stack of
+ previously visited basic blocks before recursing instead of only one
+ basic block.
+
+2013-11-25 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * config/aarch64/aarch64.c (cortexa53_tuning): New struct.
+ * config/aarch64/aarch64-cores.def (cortex-a53):
+ Use cortexa53 tuning struct.
+
+2013-11-25 Andrew Macleod <amacleod@redhat.com>
+
+ PR bootstrap/59260
+ * fold-const.c: Include hash-table.h.
+
+2013-11-25 Marek Polacek <polacek@redhat.com>
+
+ PR sanitizer/59258
+ * ubsan.c (ubsan_create_data): Increase the size of the fields array.
+
+2013-11-25 Richard Biener <rguenther@suse.de>
+
+ * tree-dfa.c: Remove unused convert.h include.
+
+2013-11-25 Terry Guo <terry.guo@arm.com>
+
+ * doc/invoke.texi (-mslow-flash-data): Document new option.
+ * config/arm/arm.opt (mslow-flash-data): New option.
+ * config/arm/arm-protos.h (arm_max_const_double_inline_cost): Declare
+ it.
+ * config/arm/arm.h (TARGET_USE_MOVT): Always true when literal pools
+ are disabled.
+ (arm_disable_literal_pool): Declare it.
+ * config/arm/arm.c (arm_disable_literal_pool): New variable.
+ (arm_option_override): Handle new option.
+ (thumb2_legitimate_address_p): Don't allow symbol references when
+ literal pools are disabled.
+ (arm_max_const_double_inline_cost): New function.
+ * config/arm/arm.md (types.md): Include it before ...
+ (use_literal_pool): New attribute.
+ (enabled): Use new attribute.
+ (split pattern): Replace symbol+offset with MOVW/MOVT.
+
+2013-11-24 Steven Bosscher <steven@gcc.gnu.org>
+
+ PR bootstrap/59279
+ Revert previous commit.
+
+2013-11-24 Steven Bosscher <steven@gcc.gnu.org>
+
+ * jump.c (reset_insn_reg_label_operand_notes): New function,
+ split out from ...
+ (init_label_info): ... here. Reset LABEL_NUSES in cfglayout mode.
+ * cfgcleanup.c (delete_dead_jump_tables_between): New function,
+ split out from ...
+ (delete_dead_jumptables): ... here. Handle cfglayout mode.
+ (cleanup_cfg): Delete dead jump tables in cfglayout mode if an
+ expensive CFG cleanup is called for.
+ * cfgrtl.c (fixup_reorder_chain): Remove BARRIERs from fallthru paths.
+ (cfg_layout_finalize): Delete dead jump tables before re-building
+ the insns chain.
+ * ira.c (ira): Rebuild jump labels *after* deleting unreachable
+ basic blocks, not before.
+ * loop-init.c (rtl_loop_done): Call for an expensive CFG cleanup.
+
+ * modulo-sched.c (sms_schedule): Do not look for BARRIERs in the
+ insns chain of a scheduling extended basic block, they cannot appear
+ there in cfglayout mode.
+
+2013-11-24 Tobias Burnus <burnus@net-b.de>
+
+ * doc/invoke.texi (-fsanitize=leak): Add link to the wiki page.
+
+2013-11-24 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
+
+ * config/rs6000/rs6000.c (rs6000_expand_vec_perm_const_1): Correct
+ for little endian.
+
+2013-11-24 H.J. Lu <hongjiu.lu@intel.com>
+
+ * graphite-sese-to-poly.c: Don't include extra "expr.h".
+
+2013-11-23 Eric Botcazou <ebotcazou@adacore.com>
+
+ * cilk-common.c (expand_builtin_cilk_detach): Dereference worker.
+
+2013-11-23 David Edelson <dje.gcc@gmail.com>
+ Andrew Dixie <andrewd@gentrack.com>
+
+ PR target/33704
+ * config/rs6000/aix.h (COLLECT_SHARED_INIT_FUNC): Define.
+ (COLLECT_SHARED_FINI_FUNC): Define.
+
+ * collect2.c (aix_shared_initname): Declare.
+ (aix_shared_fininame): Declare.
+ (symkind): Add SYM_AIXI and SYM_AIXD.
+ (scanfilter_masks): Add SCAN_AIXI and SCAN_AIXD.
+ (struct names special): Add GLOBAL__AIXI_ and GLOBAL__AIXD_.
+ (aixlazy_flag): Parse.
+ (extract_init_priority): SYM_AIXI and SYM_AIXD have highest priority.
+ (scan_prog_file, COFF): Handle SYM_AIXI and SYM_AIXD.
+
+2013-11-23 David Edelsohn <dje.gcc@gmail.com>
+
+ * config/rs6000/rs6000.c (IN_NAMED_SECTION): New macro.
+ (rs6000_xcoff_select_section): Place decls with stricter alignment
+ into named sections.
+ (rs6000_xcoff_unique_section): Allow unique sections for
+ uninitialized data with strict alignment.
+
+2013-11-23 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/59154
+ * tree-ssa-reassoc.c (maybe_optimize_range_tests): When changing
+ rhs1 of a cast and new_op is invariant, fold_convert it.
+ * tree-ssa-forwprop.c (ssa_forward_propagate_and_combine): Only call
+ simplify_conversion_from_bitmask if rhs1 is a SSA_NAME.
+
+2013-11-23 Uros Bizjak <ubizjak@gmail.com>
+
+ PR target/56788
+ * config/i386/i386.c (bdesc_multi_arg) <IX86_BUILTIN_VFRCZSS>:
+ Declare as MULTI_ARG_1_SF instruction.
+ <IX86_BUILTIN_VFRCZSD>: Decleare as MULTI_ARG_1_DF instruction.
+ * config/i386/sse.md (*xop_vmfrcz<mode>2): Rename
+ from *xop_vmfrcz_<mode>.
+ * config/i386/xopintrin.h (_mm_frcz_ss): Use __builtin_ia32_movss
+ to merge scalar result with __A.
+ (_mm_frcz_sd): Use __builtin_ia32_movsd to merge scalar
+ result with __A.
+
+2013-11-23 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gimplify.h (recalculate_side_effects): Delete.
+ * gimplify.c (recalculate_side_effects): Make static and add comment.
+
+2013-11-23 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * config/sh/sh.md: Use nonimmediate_operand rather than general_operand
+ for the destination of a define_peephole2. Likewise register_operand
+ rather than arith_reg_operand. Remove constraints from
+ define_peephole2s.
+
+2013-11-23 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * config/mn10300/mn10300-protos.h (mn10300_store_multiple_operation):
+ Delete.
+ (mn10300_store_multiple_operation_p): Declare.
+ * config/mn10300/mn10300.c (mn10300_store_multiple_operation):
+ Rename to...
+ (mn10300_store_multiple_operation_p): ...this and remove mode
+ argument.
+ * config/mn10300/predicates.md (mn10300_store_multiple_operation):
+ Define.
+
+2013-11-23 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * config/bfin/bfin-protos.h (push_multiple_operation): Delete.
+ (pop_multiple_operation): Delete.
+ (analyze_push_multiple_operation): Declare.
+ (analyze_pop_multiple_operation): Declare.
+ * config/bfin/bfin.c (push_multiple_operation): Rename to...
+ (analyze_push_multiple_operation): ...this and remove mode argument.
+ (pop_multiple_operation): Rename to...
+ (analyze_pop_multiple_operation): ...this and remove mode argument.
+ * config/bfin/predicates.md (push_multiple_operation): Define.
+ (pop_multiple_operation): Likewise.
+
+2013-11-23 Alan Modra <amodra@gmail.com>
+
+ * config/rs6000/vsx.md (fusion peepholes): Disable when !TARGET_VSX.
+
+2013-11-22 Jakub Jelinek <jakub@redhat.com>
+
+ PR sanitizer/59061
+ * common.opt (static-liblsan): Add.
+ * config/gnu-user.h (STATIC_LIBLSAN_LIBS, STATIC_LIBUBSAN_LIBS):
+ Define.
+ * flag-types.h (enum sanitize_code): Add SANITIZE_LEAK. Renumber
+ SANITIZE_SHIFT, SANITIZE_DIVIDE, SANITIZE_UNREACHABLE, SANITIZE_VLA,
+ SANITIZE_RETURN.
+ * opts.c (common_handle_option): Handle -fsanitize=leak.
+ * gcc.c (ADD_STATIC_LIBLSAN_LIBS, LIBLSAN_SPEC): Define.
+ (LIBUBSAN_SPEC): Don't test LIBUBSAN_EARLY_SPEC.
+ (LIBUBSAN_EARLY_SPEC): Remove.
+ (SANITIZER_EARLY_SPEC): Don't do anything for libubsan.
+ (SANITIZER_SPEC): Add -fsanitize=leak handling.
+ (sanitize_spec_function): Handle %sanitize(leak).
+ * doc/invoke.texi (-static-liblsan, -fsanitize=leak): Document.
+
+2013-11-22 Aldy Hernandez <aldyh@redhat.com>
+ Jakub Jelinek <jakub@redhat.com>
+
+ * ipa.c (symtab_remove_unreachable_nodes): Fix up comment typos.
+ * ipa-prop.c (get_vector_of_formal_parm_types): Renamed to ...
+ (ipa_get_vector_of_formal_parm_types): ... this. No longer static.
+ (ipa_modify_formal_parameters): Adjust caller. Remove
+ synth_parm_prefix argument. Use operator enum instead of bit fields.
+ Add assert for properly handling vector of references. Handle
+ creating brand new parameters.
+ (ipa_modify_call_arguments): Use operator enum instead of bit
+ fields.
+ (ipa_combine_adjustments): Same. Assert that IPA_PARM_OP_NEW is not
+ used.
+ (ipa_modify_expr, get_ssa_base_param, ipa_get_adjustment_candidate):
+ New functions.
+ (ipa_dump_param_adjustments): Rename reduction to new_decl.
+ Use operator enum instead of bit fields.
+ * ipa-prop.h (enum ipa_parm_op): New.
+ (struct ipa_parm_adjustment): New field op. Rename reduction
+ to new_decl, new_arg_prefix to arg_prefix and remove remove_param
+ and copy_param.
+ (ipa_modify_formal_parameters): Remove last argument.
+ (ipa_get_vector_of_formal_parm_types, ipa_modify_expr,
+ ipa_get_adjustment_candidate): New prototypes.
+ * tree-sra.c (turn_representatives_into_adjustments): Use operator
+ enum. Set arg_prefix.
+ (get_adjustment_for_base): Use operator enum.
+ (sra_ipa_modify_expr): Rename to ipa_modify_expr and move to
+ ipa-prop.c.
+ (sra_ipa_modify_assign): Rename sra_ipa_modify_expr to ipa_modify_expr.
+ (ipa_sra_modify_function_body): Same. No longer static.
+ (sra_ipa_reset_debug_stmts): Use operator enum.
+ (modify_function): Do not pass prefix argument.
+
+2013-11-22 Jakub Jelinek <jakub@redhat.com>
+
+ * ubsan.c (ubsan_source_location): Don't crash on unknown locations.
+ (ubsan_pass): Ignore clobber stmts.
+
+ * sanitizer.def (BUILT_IN_UBSAN_HANDLE_MISSING_RETURN): New built-in.
+ * opts.c (common_handle_option): Add -fsanitize=return.
+ * flag-types.h (enum sanitize_code): Add SANITIZE_RETURN and
+ or it into SANITIZE_UNDEFINED.
+
+ * sanitizer.def (BUILT_IN_ASAN_BEFORE_DYNAMIC_INIT,
+ BUILT_IN_ASAN_AFTER_DYNAMIC_INIT): New.
+ * asan.c (instrument_derefs): Handle also VAR_DECL loads/stores.
+ Don't instrument accesses to VAR_DECLs which are known to fit
+ into their bounds and the vars are known to have shadow bytes
+ indicating allowed access.
+ (asan_dynamic_init_call): New function.
+ (asan_add_global): If vnode->dynamically_initialized,
+ set __has_dynamic_init to 1 instead of 0.
+ (initialize_sanitizer_builtins): Add BT_FN_VOID_CONST_PTR var.
+ * asan.h (asan_dynamic_init_call): New prototype.
+ * cgraph.h (varpool_node): Add dynamically_initialized bitfield.
+
+2013-11-22 Martin Jambor <mjambor@suse.cz>
+
+ PR rtl-optimization/10474
+ * ira.c (interesting_dest_for_shprep_1): New function.
+ (interesting_dest_for_shprep): Use interesting_dest_for_shprep_1,
+ also check parallels.
+
+2013-11-22 Jeff Law <law@redhat.com>
+
+ * tree-ssa-threadedge.c (record_temporary_equivalence): Handle
+ NULL for RHS, which we used to invalidate equivalences.
+ (record_temporary_equivalences_from_phis): New bitmap arguments
+ and a boolean indicating if we have passed a backedge. If we
+ have passed a backedge, then set the appropriate bit in the
+ bitmaps for the SRC & DEST of PHIs creating equivalences.
+ (invalidate_equivalences, dummy_simplify): New functions.
+ (cond_arg_set_in_b): Remove.
+ (record_temporary_equivalences_from_stmts_at_dest): New bitmap
+ arguments and a boolean indicating if we have passed a backedge.
+ If we have passed a backedge, then perform invalidations as needed.
+ (thread_around_empty_blocks): If we have seen a backedge, then
+ use the dummy simplify routine.
+ (thread_through_normal_block): Likewise. Pass bitmaps and
+ backedge status to children. Do not pessimize so much when
+ traversing backedges in the CFG.
+ (thread_across_edge): Manage the SRC_MAP/DST_MAP bitmaps.
+ If we have seen a backedge, then use the dummy simplify routine.
+ Do not pessimize so much when traversing backedges.
+
+2013-11-22 Hans-Peter Nilsson <hp@axis.com>
+
+ * config/cris/cris.c (cris_atomic_align_for_mode): New function.
+ (TARGET_ATOMIC_ALIGN_FOR_MODE): Define.
+
+2013-11-22 Yuri Rumyantsev <ysrumyan@gmail.com>
+
+ * config/i386/i386.c(processor_alias_table): Enable PTA_AES,
+ PTA_PCLMUL and PTA_RDRND for Silvermont.
+ * config/i386/driver-i386.c (host_detect_local_cpu): Set up cpu
+ for Silvermont.
+
+ * doc/invoke.texi: Mention AES, PCLMUL and RDRND for Silvermont.
+
+2013-11-22 Andrew MacLeod <amacleod@redhat.com>
+
+ * hooks.h (hook_uint_mode_0): Add Prototype.
+ * hooks.c (hook_uint_mode_0): New default function.
+ * target.def (atomic_align_for_mode): New target hook.
+ * tree.c (build_atomic_base): Add alignment override parameter.
+ (build_common_tree_nodes): Use atomic alignment override.
+ * doc/tm.texi.in (TARGET_ATOMIC_ALIGN_FOR_MODE): Define.
+ * doc/tm.texi (TARGET_ATOMIC_ALIGN_FOR_MODE): Add description.
+
+2013-11-22 Andrew MacLeod <amacleod@redhat.com>
+
+ * gimple.h: Remove all includes.
+ (recalculate_side_effects): Move prototype to gimplify.h.
+ * Makefile.in (PLUGIN_HEADERS): Add flattened gimple.h includes.
+ * gengtype.c (open_base_files): Add gimple.h include list.
+ * gimplify.h (recalculate_side_effects): Relocate prototype here.
+ * gimple.c: Adjust include list.
+ (recalculate_side_effects): Move to gimplify.c.
+ * gimplify.c: Adjust include list.
+ (recalculate_side_effects): Relocate from gimple.c.
+ * alias.c: Add required include files removed from gimple.h.
+ * asan.c: Likewise.
+ * builtins.c: Likewise.
+ * calls.c: Likewise.
+ * cfgexpand.c: Likewise.
+ * cfgloop.c: Likewise.
+ * cfgloopmanip.c: Likewise.
+ * cgraphbuild.c: Likewise.
+ * cgraph.c: Likewise.
+ * cgraphclones.c: Likewise.
+ * cgraphunit.c: Likewise.
+ * cilk-common.c: Likewise.
+ * data-streamer.c: Likewise.
+ * data-streamer-in.c: Likewise.
+ * data-streamer-out.c: Likewise.
+ * dse.c: Likewise.
+ * dwarf2out.c: Likewise.
+ * emit-rtl.c: Likewise.
+ * except.c: Likewise.
+ * expr.c: Likewise.
+ * fold-const.c: Likewise.
+ * function.c: Likewise.
+ * gimple-builder.c: Likewise.
+ * gimple-expr.c: Likewise.
+ * gimple-fold.c: Likewise.
+ * gimple-iterator.c: Likewise.
+ * gimple-low.c: Likewise.
+ * gimple-pretty-print.c: Likewise.
+ * gimple-ssa-isolate-paths.c: Likewise.
+ * gimple-ssa-strength-reduction.c: Likewise.
+ * gimple-streamer-in.c: Likewise.
+ * gimple-streamer-out.c: Likewise.
+ * gimple-walk.c: Likewise.
+ * gimplify-me.c: Likewise.
+ * graphite-blocking.c: Likewise.
+ * graphite.c: Likewise.
+ * graphite-clast-to-gimple.c: Likewise.
+ * graphite-dependences.c: Likewise.
+ * graphite-interchange.c: Likewise.
+ * graphite-optimize-isl.c: Likewise.
+ * graphite-poly.c: Likewise.
+ * graphite-scop-detection.c: Likewise.
+ * graphite-sese-to-poly.c: Likewise.
+ * internal-fn.c: Likewise.
+ * ipa.c: Likewise.
+ * ipa-cp.c: Likewise.
+ * ipa-devirt.c: Likewise.
+ * ipa-inline-analysis.c: Likewise.
+ * ipa-inline.c: Likewise.
+ * ipa-profile.c: Likewise.
+ * ipa-prop.c: Likewise.
+ * ipa-pure-const.c: Likewise.
+ * ipa-reference.c: Likewise.
+ * ipa-split.c: Likewise.
+ * ipa-utils.c: Likewise.
+ * langhooks.c: Likewise.
+ * lto-cgraph.c: Likewise.
+ * lto-compress.c: Likewise.
+ * lto-opts.c: Likewise.
+ * lto-section-in.c: Likewise.
+ * lto-section-out.c: Likewise.
+ * lto-streamer.c: Likewise.
+ * lto-streamer-in.c: Likewise.
+ * lto-streamer-out.c: Likewise.
+ * omp-low.c: Likewise.
+ * opts-global.c: Likewise.
+ * passes.c: Likewise.
+ * predict.c: Likewise.
+ * profile.c: Likewise.
+ * sese.c: Likewise.
+ * stmt.c: Likewise.
+ * stor-layout.c: Likewise.
+ * symtab.c: Likewise.
+ * targhooks.c: Likewise.
+ * toplev.c: Likewise.
+ * tracer.c: Likewise.
+ * trans-mem.c: Likewise.
+ * tree-affine.c: Likewise.
+ * tree.c: Likewise.
+ * tree-call-cdce.c: Likewise.
+ * tree-cfg.c: Likewise.
+ * tree-cfgcleanup.c: Likewise.
+ * tree-chrec.c: Likewise.
+ * tree-complex.c: Likewise.
+ * tree-data-ref.c: Likewise.
+ * tree-dfa.c: Likewise.
+ * tree-eh.c: Likewise.
+ * tree-emutls.c: Likewise.
+ * tree-if-conv.c: Likewise.
+ * tree-inline.c: Likewise.
+ * tree-into-ssa.c: Likewise.
+ * tree-loop-distribution.c: Likewise.
+ * tree-nested.c: Likewise.
+ * tree-nrv.c: Likewise.
+ * tree-object-size.c: Likewise.
+ * tree-outof-ssa.c: Likewise.
+ * tree-parloops.c: Likewise.
+ * tree-phinodes.c: Likewise.
+ * tree-predcom.c: Likewise.
+ * tree-pretty-print.c: Likewise.
+ * tree-profile.c: Likewise.
+ * tree-scalar-evolution.c: Likewise.
+ * tree-sra.c: Likewise.
+ * tree-ssa-address.c: Likewise.
+ * tree-ssa-alias.c: Likewise.
+ * tree-ssa.c: Likewise.
+ * tree-ssa-ccp.c: Likewise.
+ * tree-ssa-coalesce.c: Likewise.
+ * tree-ssa-copy.c: Likewise.
+ * tree-ssa-copyrename.c: Likewise.
+ * tree-ssa-dce.c: Likewise.
+ * tree-ssa-dom.c: Likewise.
+ * tree-ssa-dse.c: Likewise.
+ * tree-ssa-forwprop.c: Likewise.
+ * tree-ssa-ifcombine.c: Likewise.
+ * tree-ssa-live.c: Likewise.
+ * tree-ssa-loop.c: Likewise.
+ * tree-ssa-loop-ch.c: Likewise.
+ * tree-ssa-loop-im.c: Likewise.
+ * tree-ssa-loop-ivcanon.c: Likewise.
+ * tree-ssa-loop-ivopts.c: Likewise.
+ * tree-ssa-loop-manip.c: Likewise.
+ * tree-ssa-loop-niter.c: Likewise.
+ * tree-ssa-loop-prefetch.c: Likewise.
+ * tree-ssa-loop-unswitch.c: Likewise.
+ * tree-ssa-math-opts.c: Likewise.
+ * tree-ssanames.c: Likewise.
+ * tree-ssa-operands.c: Likewise.
+ * tree-ssa-phiopt.c: Likewise.
+ * tree-ssa-phiprop.c: Likewise.
+ * tree-ssa-pre.c: Likewise.
+ * tree-ssa-propagate.c: Likewise.
+ * tree-ssa-reassoc.c: Likewise.
+ * tree-ssa-sccvn.c: Likewise.
+ * tree-ssa-sink.c: Likewise.
+ * tree-ssa-strlen.c: Likewise.
+ * tree-ssa-structalias.c: Likewise.
+ * tree-ssa-tail-merge.c: Likewise.
+ * tree-ssa-ter.c: Likewise.
+ * tree-ssa-threadedge.c: Likewise.
+ * tree-ssa-threadupdate.c: Likewise.
+ * tree-ssa-uncprop.c: Likewise.
+ * tree-ssa-uninit.c: Likewise.
+ * tree-stdarg.c: Likewise.
+ * tree-streamer.c: Likewise.
+ * tree-streamer-in.c: Likewise.
+ * tree-streamer-out.c: Likewise.
+ * tree-switch-conversion.c: Likewise.
+ * tree-tailcall.c: Likewise.
+ * tree-vect-data-refs.c: Likewise.
+ * tree-vect-generic.c: Likewise.
+ * tree-vect-loop.c: Likewise.
+ * tree-vect-loop-manip.c: Likewise.
+ * tree-vectorizer.c: Likewise.
+ * tree-vect-patterns.c: Likewise.
+ * tree-vect-slp.c: Likewise.
+ * tree-vect-stmts.c: Likewise.
+ * tree-vrp.c: Likewise.
+ * tsan.c: Likewise.
+ * ubsan.c: Likewise.
+ * value-prof.c: Likewise.
+ * varpool.c: Likewise.
+ * var-tracking.c: Likewise.
+ * vtable-verify.c: Likewise.
+ * config/darwin.c: Likewise.
+ * config/aarch64/aarch64-builtins.c: Likewise.
+ * config/aarch64/aarch64.c: Likewise.
+ * config/alpha/alpha.c: Likewise.
+ * config/i386/i386.c: Likewise.
+ * config/i386/winnt.c: Likewise.
+ * config/ia64/ia64.c: Likewise.
+ * config/m32c/m32c.c: Likewise.
+ * config/mep/mep.c: Likewise.
+ * config/mips/mips.c: Likewise.
+ * config/rs6000/rs6000.c: Likewise.
+ * config/s390/s390.c: Likewise.
+ * config/sh/sh.c: Likewise.
+ * config/sparc/sparc.c: Likewise.
+ * config/spu/spu.c: Likewise.
+ * config/stormy16/stormy16.c: Likewise.
+ * config/tilegx/tilegx.c: Likewise.
+ * config/tilepro/tilepro.c: Likewise.
+ * config/xtensa/xtensa.c: Likewise.
+
+2013-11-22 Richard Earnshaw <rearnsha@arm.com>
+
+ PR target/59216
+ * arm.md (negdi_extendsidi): Fix invalid split.
+
+2013-11-22 Alex Velenko <Alex.Velenko@arm.com>
+
+ * config/aarch64/arm_neon.h (vmov_n_f32): Implemented in C.
+ (vmov_n_f64): Likewise.
+ (vmov_n_p8): Likewise.
+ (vmov_n_p16): Likewise.
+ (vmov_n_s8): Likewise.
+ (vmov_n_s16): Likewise.
+ (vmov_n_s32): Likewise.
+ (vmov_n_s64): Likewise.
+ (vmov_n_u8): Likewise.
+ (vmov_n_u16): Likewise.
+ (vmov_n_u32): Likewise.
+ (vmov_n_u64): Likewise.
+ (vmovq_n_f32): Likewise.
+ (vmovq_n_f64): Likewise.
+ (vmovq_n_p8): Likewise.
+ (vmovq_n_p16): Likewise.
+ (vmovq_n_s8): Likewise.
+ (vmovq_n_s16): Likewise.
+ (vmovq_n_s32): Likewise.
+ (vmovq_n_s64): Likewise.
+ (vmovq_n_u8): Likewise.
+ (vmovq_n_u16): Likewise.
+ (vmovq_n_u32): Likewise.
+ (vmovq_n_u64): Likewise.
+
+2013-11-22 Tejas Belagod <tejas.belagod@arm.com>
+
+ * config/aarch64/aarch64-simd.md (vec_pack_trunc_<mode>,
+ vec_pack_trunc_v2df, vec_pack_trunc_df): Swap for big-endian.
+ (reduc_<sur>plus_<mode>): Factorize V2DI into this.
+ (reduc_<sur>plus_<mode>): Change this to reduc_splus_<mode> for floats
+ and also change to float UNSPEC.
+ (reduc_maxmin_uns>_<mode>): Remove V2DI.
+ * config/aarch64/arm_neon.h (vaddv<q>_<suf><8,16,32,64>,
+ vmaxv<q>_<suf><8,16,32,64>, vminv<q>_<suf><8,16,32,64>): Fix up scalar
+ result access for big-endian.
+ (__LANE0): New macro used to fix up lane access of 'across-lanes'
+ intrinsics for big-endian.
+ * config/aarch64/iterators.md (VDQV): Add V2DI.
+ (VDQV_S): New.
+ (vp): New mode attribute.
+
+2013-11-22 Tejas Belagod <tejas.belagod@arm.com>
+
+ * config/aarch64/aarch64-simd.md (vec_pack_trunc_<mode>,
+ vec_pack_trunc_v2df, vec_pack_trunc_df): Swap source ops for
+ big-endian.
+
+2013-11-22 Tejas Belagod <tejas.belagod@arm.com>
+
+ * config/aarch64/aarch64-simd.md (aarch64_simd_vec_set<mode>): Adjust
+ for big-endian element order.
+ (aarch64_simd_vec_setv2di): Likewise.
+ (*aarch64_get_lane_extend<GPI:mode><VDQQH:mode>,
+ *aarch64_get_lane_zero_extendsi<mode>, aarch64_get_lane): Likewise.
+ (vec_extract): Expand using aarch64_get_lane.
+ * config/aarch64/aarch64.h (ENDIAN_LANE_N): New.
+
+2013-11-22 Tejas Belagod <tejas.belagod@arm.com>
+
+ * config/aarch64/aarch64-simd.md (*aarch64_simd_mov<mode>): Fix loads
+ and stores to be ABI compliant.
+
+2013-11-22 David Malcolm <dmalcolm@redhat.com>
+
+ * input.h (input_line): Remove.
+ (input_filename): Likewise.
+ (in_system_header): Likewise.
+ * tree.h (EXPR_LOC_OR_HERE): Remove.
+ * config/bfin/bfin.c (output_file_start): Remove use of
+ input_filename macro.
+ * builtins.c (c_strlen): Remove use of EXPR_LOC_OR_HERE macro.
+ * gimplify.c (internal_get_tmp_var): Likewise.
+ EXPR_LOC_OR_HERE macro.
+ (shortcut_cond_expr): Likewise.
+ * tree-diagnostic.c (diagnostic_report_current_function): Remove
+ use of input_filename macro.
+ * tree.c (get_file_function_name): Likewise.
+
2013-11-22 Kenneth Zadeck <zadeck@naturalbridge.com>
* store-layout.c (place-field): Fix hwi test and accessor mismatch.
$(mkinstalldirs) $(DESTDIR)$(man7dir)
PLUGIN_HEADERS = $(TREE_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
- toplev.h $(DIAGNOSTIC_CORE_H) $(BASIC_BLOCK_H) $(GIMPLE_H) $(TREE_PASS_H) $(GCC_PLUGIN_H) \
+ toplev.h $(DIAGNOSTIC_CORE_H) $(BASIC_BLOCK_H) pointer-set.h $(HASH_TABLE_H) \
+ tree-ssa-alias.h $(INTERNAL_FN_H) gimple-fold.h tree-eh.h gimple-expr.h \
+ gimple.h is-a.h $(TREE_PASS_H) $(GCC_PLUGIN_H) \
$(GGC_H) $(TREE_DUMP_H) $(PRETTY_PRINT_H) $(OPTS_H) $(PARAMS_H) \
$(tm_file_list) $(tm_include_list) $(tm_p_file_list) $(tm_p_include_list) \
$(host_xm_file_list) $(host_xm_include_list) $(xm_include_list) \
+2013-11-29 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR ada/54040
+ PR ada/59346
+ * s-osinte-hpux.ads (timespec): Change type of tv_nsec field to time_t.
+ * s-osinte-kfreebsd-gnu.ads (timespec): Likewise.
+ * s-osinte-solaris-posix.ads (timespec): Likewise.
+
+2013-11-23 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interface/trans.c (Loop_Statement_to_gnu): Set TREE_SIDE_EFFECTS
+ on the conditional expression directly.
+
+2013-11-22 Andrew MacLeod <amacleod@redhat.com>
+
+ * gcc-interface/trans.c: Add required include files from gimple.h.
+
+2013-11-22 David Malcolm <dmalcolm@redhat.com>
+
+ * gcc-interface/utils2.c (build_call_raise): Remove use of
+ input_line macro.
+ (build_call_raise_range): Likewise.
+ (build_call_raise_column): Likewise.
+
2013-11-20 Kenneth Zadeck <zadeck@naturalbridge.com>
Mike Stump <mikestump@comcast.net>
Richard Sandiford <rdsandiford@googlemail.com>
#include "stmt.h"
#include "varasm.h"
#include "flags.h"
-#include "ggc.h"
#include "output.h"
#include "libfuncs.h" /* For set_stack_check_libfunc. */
#include "tree-iterator.h"
-#include "gimple.h"
-#include "gimplify.h"
#include "pointer-set.h"
+#include "gimple-expr.h"
+#include "gimplify.h"
#include "bitmap.h"
#include "cgraph.h"
#include "diagnostic.h"
if (gnu_cond_expr)
{
COND_EXPR_THEN (gnu_cond_expr) = gnu_loop_stmt;
+ TREE_SIDE_EFFECTS (gnu_cond_expr) = 1;
gnu_result = gnu_cond_expr;
- recalculate_side_effects (gnu_cond_expr);
}
else
gnu_result = gnu_loop_stmt;
filename = build_string (len, str);
line_number
= (gnat_node != Empty && Sloc (gnat_node) != No_Location)
- ? Get_Logical_Line_Number (Sloc(gnat_node)) : input_line;
+ ? Get_Logical_Line_Number (Sloc(gnat_node))
+ : LOCATION_LINE (input_location);
TREE_TYPE (filename) = build_array_type (unsigned_char_type_node,
build_index_type (size_int (len)));
}
else
{
- line_number = input_line;
+ line_number = LOCATION_LINE (input_location);
column_number = 0;
}
}
else
{
- line_number = input_line;
+ line_number = LOCATION_LINE (input_location);
column_number = 0;
}
-- S p e c --
-- --
-- Copyright (C) 1991-1994, Florida State University --
--- Copyright (C) 1995-2012, Free Software Foundation, Inc. --
+-- Copyright (C) 1995-2013, 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- --
type timespec is record
tv_sec : time_t;
- tv_nsec : long;
+ tv_nsec : time_t;
end record;
pragma Convention (C, timespec);
-- --
-- S p e c --
-- --
--- Copyright (C) 1991-1994, Florida State University --
--- Copyright (C) 1995-2005,2008,2012 Free Software Foundation, Inc. --
+-- Copyright (C) 1991-1994, Florida State University --
+-- Copyright (C) 1995-2013, 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- --
type timespec is record
tv_sec : time_t;
- tv_nsec : long;
+ tv_nsec : time_t;
end record;
pragma Convention (C, timespec);
-- S p e c --
-- --
-- Copyright (C) 1991-1994, Florida State University --
--- Copyright (C) 1995-2011, Free Software Foundation, Inc. --
+-- Copyright (C) 1995-2013, 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- --
type timespec is record
tv_sec : time_t;
- tv_nsec : long;
+ tv_nsec : time_t;
end record;
pragma Convention (C, timespec);
#include "emit-rtl.h"
#include "regs.h"
#include "hard-reg-set.h"
-#include "basic-block.h"
#include "flags.h"
#include "diagnostic-core.h"
#include "cselib.h"
#include "splay-tree.h"
-#include "ggc.h"
#include "langhooks.h"
#include "timevar.h"
#include "dumpfile.h"
#include "df.h"
#include "tree-ssa-alias.h"
#include "pointer-set.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-ssa.h"
#include "system.h"
#include "coretypes.h"
#include "tree.h"
+#include "hash-table.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimplify.h"
#include "gimple-iterator.h"
#include "output.h"
#include "tm_p.h"
#include "langhooks.h"
-#include "hash-table.h"
#include "alloc-pool.h"
#include "cfgloop.h"
#include "gimple-builder.h"
// Name of the module where the global variable is declared.
const void *__module_name;
- // This is always set to NULL for now.
+ // 1 if it has dynamic initialization, 0 otherwise.
uptr __has_dynamic_init;
}
alias set is used for all shadow memory accesses. */
static GTY(()) tree shadow_ptr_types[2];
+/* Decl for __asan_option_detect_stack_use_after_return. */
+static GTY(()) tree asan_detect_stack_use_after_return;
+
/* Hashtable support for memory references used by gimple
statements. */
and DECLS is an array of representative decls for each var partition.
LENGTH is the length of the OFFSETS array, DECLS array is LENGTH / 2 - 1
elements long (OFFSETS include gap before the first variable as well
- as gaps after each stack variable). */
+ as gaps after each stack variable). PBASE is, if non-NULL, some pseudo
+ register which stack vars DECL_RTLs are based on. Either BASE should be
+ assigned to PBASE, when not doing use after return protection, or
+ corresponding address based on __asan_stack_malloc* return value. */
rtx
-asan_emit_stack_protection (rtx base, HOST_WIDE_INT *offsets, tree *decls,
- int length)
+asan_emit_stack_protection (rtx base, rtx pbase, unsigned int alignb,
+ HOST_WIDE_INT *offsets, tree *decls, int length)
{
- rtx shadow_base, shadow_mem, ret, mem;
+ rtx shadow_base, shadow_mem, ret, mem, orig_base, lab;
char buf[30];
unsigned char shadow_bytes[4];
- HOST_WIDE_INT base_offset = offsets[length - 1], offset, prev_offset;
+ HOST_WIDE_INT base_offset = offsets[length - 1];
+ HOST_WIDE_INT base_align_bias = 0, offset, prev_offset;
+ HOST_WIDE_INT asan_frame_size = offsets[0] - base_offset;
HOST_WIDE_INT last_offset, last_size;
int l;
unsigned char cur_shadow_byte = ASAN_STACK_MAGIC_LEFT;
tree str_cst, decl, id;
+ int use_after_return_class = -1;
if (shadow_ptr_types[0] == NULL_TREE)
asan_init_shadow_ptr_types ();
str_cst = asan_pp_string (&asan_pp);
/* Emit the prologue sequence. */
+ if (asan_frame_size > 32 && asan_frame_size <= 65536 && pbase)
+ {
+ use_after_return_class = floor_log2 (asan_frame_size - 1) - 5;
+ /* __asan_stack_malloc_N guarantees alignment
+ N < 6 ? (64 << N) : 4096 bytes. */
+ if (alignb > (use_after_return_class < 6
+ ? (64U << use_after_return_class) : 4096U))
+ use_after_return_class = -1;
+ else if (alignb > ASAN_RED_ZONE_SIZE && (asan_frame_size & (alignb - 1)))
+ base_align_bias = ((asan_frame_size + alignb - 1)
+ & ~(alignb - HOST_WIDE_INT_1)) - asan_frame_size;
+ }
+ if (use_after_return_class == -1 && pbase)
+ emit_move_insn (pbase, base);
base = expand_binop (Pmode, add_optab, base,
- gen_int_mode (base_offset, Pmode),
+ gen_int_mode (base_offset - base_align_bias, Pmode),
NULL_RTX, 1, OPTAB_DIRECT);
+ orig_base = NULL_RTX;
+ if (use_after_return_class != -1)
+ {
+ if (asan_detect_stack_use_after_return == NULL_TREE)
+ {
+ id = get_identifier ("__asan_option_detect_stack_use_after_return");
+ decl = build_decl (BUILTINS_LOCATION, VAR_DECL, id,
+ integer_type_node);
+ SET_DECL_ASSEMBLER_NAME (decl, id);
+ TREE_ADDRESSABLE (decl) = 1;
+ DECL_ARTIFICIAL (decl) = 1;
+ DECL_IGNORED_P (decl) = 1;
+ DECL_EXTERNAL (decl) = 1;
+ TREE_STATIC (decl) = 1;
+ TREE_PUBLIC (decl) = 1;
+ TREE_USED (decl) = 1;
+ asan_detect_stack_use_after_return = decl;
+ }
+ orig_base = gen_reg_rtx (Pmode);
+ emit_move_insn (orig_base, base);
+ ret = expand_normal (asan_detect_stack_use_after_return);
+ lab = gen_label_rtx ();
+ int very_likely = REG_BR_PROB_BASE - (REG_BR_PROB_BASE / 2000 - 1);
+ emit_cmp_and_jump_insns (ret, const0_rtx, EQ, NULL_RTX,
+ VOIDmode, 0, lab, very_likely);
+ snprintf (buf, sizeof buf, "__asan_stack_malloc_%d",
+ use_after_return_class);
+ ret = init_one_libfunc (buf);
+ rtx addr = convert_memory_address (ptr_mode, base);
+ ret = emit_library_call_value (ret, NULL_RTX, LCT_NORMAL, ptr_mode, 2,
+ GEN_INT (asan_frame_size
+ + base_align_bias),
+ TYPE_MODE (pointer_sized_int_node),
+ addr, ptr_mode);
+ ret = convert_memory_address (Pmode, ret);
+ emit_move_insn (base, ret);
+ emit_label (lab);
+ emit_move_insn (pbase, expand_binop (Pmode, add_optab, base,
+ gen_int_mode (base_align_bias
+ - base_offset, Pmode),
+ NULL_RTX, 1, OPTAB_DIRECT));
+ }
mem = gen_rtx_MEM (ptr_mode, base);
+ mem = adjust_address (mem, VOIDmode, base_align_bias);
emit_move_insn (mem, gen_int_mode (ASAN_STACK_FRAME_MAGIC, ptr_mode));
mem = adjust_address (mem, VOIDmode, GET_MODE_SIZE (ptr_mode));
emit_move_insn (mem, expand_normal (str_cst));
shadow_base = expand_binop (Pmode, lshr_optab, base,
GEN_INT (ASAN_SHADOW_SHIFT),
NULL_RTX, 1, OPTAB_DIRECT);
- shadow_base = expand_binop (Pmode, add_optab, shadow_base,
- gen_int_mode (targetm.asan_shadow_offset (),
- Pmode),
- NULL_RTX, 1, OPTAB_DIRECT);
+ shadow_base
+ = plus_constant (Pmode, shadow_base,
+ targetm.asan_shadow_offset ()
+ + (base_align_bias >> ASAN_SHADOW_SHIFT));
gcc_assert (asan_shadow_set != -1
&& (ASAN_RED_ZONE_SIZE >> ASAN_SHADOW_SHIFT) == 4);
shadow_mem = gen_rtx_MEM (SImode, shadow_base);
/* Construct epilogue sequence. */
start_sequence ();
+ lab = NULL_RTX;
+ if (use_after_return_class != -1)
+ {
+ rtx lab2 = gen_label_rtx ();
+ char c = (char) ASAN_STACK_MAGIC_USE_AFTER_RET;
+ int very_likely = REG_BR_PROB_BASE - (REG_BR_PROB_BASE / 2000 - 1);
+ emit_cmp_and_jump_insns (orig_base, base, EQ, NULL_RTX,
+ VOIDmode, 0, lab2, very_likely);
+ shadow_mem = gen_rtx_MEM (BLKmode, shadow_base);
+ set_mem_alias_set (shadow_mem, asan_shadow_set);
+ mem = gen_rtx_MEM (ptr_mode, base);
+ mem = adjust_address (mem, VOIDmode, base_align_bias);
+ emit_move_insn (mem, gen_int_mode (ASAN_STACK_RETIRED_MAGIC, ptr_mode));
+ unsigned HOST_WIDE_INT sz = asan_frame_size >> ASAN_SHADOW_SHIFT;
+ if (use_after_return_class < 5
+ && can_store_by_pieces (sz, builtin_memset_read_str, &c,
+ BITS_PER_UNIT, true))
+ store_by_pieces (shadow_mem, sz, builtin_memset_read_str, &c,
+ BITS_PER_UNIT, true, 0);
+ else if (use_after_return_class >= 5
+ || !set_storage_via_setmem (shadow_mem,
+ GEN_INT (sz),
+ gen_int_mode (c, QImode),
+ BITS_PER_UNIT, BITS_PER_UNIT,
+ -1, sz, sz, sz))
+ {
+ snprintf (buf, sizeof buf, "__asan_stack_free_%d",
+ use_after_return_class);
+ ret = init_one_libfunc (buf);
+ rtx addr = convert_memory_address (ptr_mode, base);
+ rtx orig_addr = convert_memory_address (ptr_mode, orig_base);
+ emit_library_call (ret, LCT_NORMAL, ptr_mode, 3, addr, ptr_mode,
+ GEN_INT (asan_frame_size + base_align_bias),
+ TYPE_MODE (pointer_sized_int_node),
+ orig_addr, ptr_mode);
+ }
+ lab = gen_label_rtx ();
+ emit_jump (lab);
+ emit_label (lab2);
+ }
+
shadow_mem = gen_rtx_MEM (BLKmode, shadow_base);
set_mem_alias_set (shadow_mem, asan_shadow_set);
prev_offset = base_offset;
}
do_pending_stack_adjust ();
+ if (lab)
+ emit_label (lab);
ret = get_insns ();
end_sequence ();
case COMPONENT_REF:
case INDIRECT_REF:
case MEM_REF:
+ case VAR_DECL:
break;
+ /* FALLTHRU */
default:
return;
}
tree offset;
enum machine_mode mode;
int volatilep = 0, unsignedp = 0;
- get_inner_reference (t, &bitsize, &bitpos, &offset,
- &mode, &unsignedp, &volatilep, false);
+ tree inner = get_inner_reference (t, &bitsize, &bitpos, &offset,
+ &mode, &unsignedp, &volatilep, false);
if (bitpos % (size_in_bytes * BITS_PER_UNIT)
|| bitsize != size_in_bytes * BITS_PER_UNIT)
{
return;
}
+ if (TREE_CODE (inner) == VAR_DECL
+ && offset == NULL_TREE
+ && bitpos >= 0
+ && DECL_SIZE (inner)
+ && tree_fits_shwi_p (DECL_SIZE (inner))
+ && bitpos + bitsize <= tree_to_shwi (DECL_SIZE (inner)))
+ {
+ if (DECL_THREAD_LOCAL_P (inner))
+ return;
+ if (!TREE_STATIC (inner))
+ {
+ /* Automatic vars in the current function will be always
+ accessible. */
+ if (decl_function_context (inner) == current_function_decl)
+ return;
+ }
+ /* Always instrument external vars, they might be dynamically
+ initialized. */
+ else if (!DECL_EXTERNAL (inner))
+ {
+ /* For static vars if they are known not to be dynamically
+ initialized, they will be always accessible. */
+ struct varpool_node *vnode = varpool_get_node (inner);
+ if (vnode && !vnode->dynamically_initialized)
+ return;
+ }
+ }
+
base = build_fold_addr_expr (t);
if (!has_mem_ref_been_instrumented (base, size_in_bytes))
{
free_mem_ref_resources ();
}
+/* Build
+ __asan_before_dynamic_init (module_name)
+ or
+ __asan_after_dynamic_init ()
+ call. */
+
+tree
+asan_dynamic_init_call (bool after_p)
+{
+ tree fn = builtin_decl_implicit (after_p
+ ? BUILT_IN_ASAN_AFTER_DYNAMIC_INIT
+ : BUILT_IN_ASAN_BEFORE_DYNAMIC_INIT);
+ tree module_name_cst = NULL_TREE;
+ if (!after_p)
+ {
+ pretty_printer module_name_pp;
+ pp_string (&module_name_pp, main_input_filename);
+
+ if (shadow_ptr_types[0] == NULL_TREE)
+ asan_init_shadow_ptr_types ();
+ module_name_cst = asan_pp_string (&module_name_pp);
+ module_name_cst = fold_convert (const_ptr_type_node,
+ module_name_cst);
+ }
+
+ return build_call_expr (fn, after_p ? 0 : 1, module_name_cst);
+}
+
/* Build
struct __asan_global
{
fold_convert (const_ptr_type_node, str_cst));
CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE,
fold_convert (const_ptr_type_node, module_name_cst));
- CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE, build_int_cst (uptr, 0));
+ struct varpool_node *vnode = varpool_get_node (decl);
+ int has_dynamic_init = vnode ? vnode->dynamically_initialized : 0;
+ CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE,
+ build_int_cst (uptr, has_dynamic_init));
init = build_constructor (type, vinner);
CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init);
}
tree BT_FN_VOID = build_function_type_list (void_type_node, NULL_TREE);
tree BT_FN_VOID_PTR
= build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
+ tree BT_FN_VOID_CONST_PTR
+ = build_function_type_list (void_type_node, const_ptr_type_node, NULL_TREE);
tree BT_FN_VOID_PTR_PTR
= build_function_type_list (void_type_node, ptr_type_node,
ptr_type_node, NULL_TREE);
extern void asan_function_start (void);
extern void asan_finish_file (void);
-extern rtx asan_emit_stack_protection (rtx, HOST_WIDE_INT *, tree *, int);
+extern rtx asan_emit_stack_protection (rtx, rtx, unsigned int, HOST_WIDE_INT *,
+ tree *, int);
extern bool asan_protect_global (tree);
extern void initialize_sanitizer_builtins (void);
+extern tree asan_dynamic_init_call (bool);
/* Alias set for accessing the shadow memory. */
extern alias_set_type asan_shadow_set;
#define ASAN_STACK_MAGIC_MIDDLE 0xf2
#define ASAN_STACK_MAGIC_RIGHT 0xf3
#define ASAN_STACK_MAGIC_PARTIAL 0xf4
+#define ASAN_STACK_MAGIC_USE_AFTER_RET 0xf5
-#define ASAN_STACK_FRAME_MAGIC 0x41b58ab3
+#define ASAN_STACK_FRAME_MAGIC 0x41b58ab3
+#define ASAN_STACK_RETIRED_MAGIC 0x45e0360e
/* Return true if DECL should be guarded on the stack. */
DEF_FUNCTION_TYPE_1 (BT_FN_UINT32_UINT32, BT_UINT32, BT_UINT32)
DEF_FUNCTION_TYPE_1 (BT_FN_UINT64_UINT64, BT_UINT64, BT_UINT64)
DEF_FUNCTION_TYPE_1 (BT_FN_BOOL_INT, BT_BOOL, BT_INT)
-DEF_FUNCTION_TYPE_1 (BT_FN_PTR_CONST_PTR, BT_PTR, BT_CONST_PTR)
-DEF_FUNCTION_TYPE_1 (BT_FN_CONST_PTR_CONST_PTR, BT_CONST_PTR, BT_CONST_PTR)
DEF_POINTER_TYPE (BT_PTR_FN_VOID_PTR, BT_FN_VOID_PTR)
BT_CONST_VOLATILE_PTR)
DEF_FUNCTION_TYPE_2 (BT_FN_BOOL_INT_BOOL, BT_BOOL, BT_INT, BT_BOOL)
DEF_FUNCTION_TYPE_2 (BT_FN_VOID_UINT_UINT, BT_VOID, BT_UINT, BT_UINT)
-DEF_FUNCTION_TYPE_2 (BT_FN_PTR_CONST_PTR_SIZE, BT_PTR, BT_CONST_PTR, BT_SIZE)
-DEF_FUNCTION_TYPE_2 (BT_FN_PTR_CONST_PTR_CONST_PTR, BT_PTR, BT_CONST_PTR, BT_CONST_PTR)
-DEF_FUNCTION_TYPE_2 (BT_FN_VOID_PTRPTR_CONST_PTR, BT_VOID, BT_PTR_PTR, BT_CONST_PTR)
-DEF_FUNCTION_TYPE_2 (BT_FN_VOID_CONST_PTR_SIZE, BT_VOID, BT_CONST_PTR, BT_SIZE)
DEF_POINTER_TYPE (BT_PTR_FN_VOID_PTR_PTR, BT_FN_VOID_PTR_PTR)
DEF_FUNCTION_TYPE_3 (BT_FN_VOID_VPTR_I4_INT, BT_VOID, BT_VOLATILE_PTR, BT_I4, BT_INT)
DEF_FUNCTION_TYPE_3 (BT_FN_VOID_VPTR_I8_INT, BT_VOID, BT_VOLATILE_PTR, BT_I8, BT_INT)
DEF_FUNCTION_TYPE_3 (BT_FN_VOID_VPTR_I16_INT, BT_VOID, BT_VOLATILE_PTR, BT_I16, BT_INT)
-DEF_FUNCTION_TYPE_3 (BT_FN_PTR_CONST_PTR_CONST_PTR_SIZE, BT_PTR, BT_CONST_PTR, BT_CONST_PTR, BT_SIZE)
DEF_FUNCTION_TYPE_4 (BT_FN_SIZE_CONST_PTR_SIZE_SIZE_FILEPTR,
BT_SIZE, BT_CONST_PTR, BT_SIZE, BT_SIZE, BT_FILEPTR)
BT_INT, BT_CONST_STRING)
DEF_FUNCTION_TYPE_VAR_1 (BT_FN_UINT32_UINT32_VAR,
BT_UINT32, BT_UINT32)
-DEF_FUNCTION_TYPE_VAR_1 (BT_FN_PTR_CONST_PTR_VAR,
- BT_PTR, BT_CONST_PTR)
DEF_FUNCTION_TYPE_VAR_2 (BT_FN_INT_FILEPTR_CONST_STRING_VAR,
BT_INT, BT_FILEPTR, BT_CONST_STRING)
#include "varasm.h"
#include "tree-object-size.h"
#include "realmpfr.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "flags.h"
#include "regs.h"
#include "tm_p.h"
#include "target.h"
#include "langhooks.h"
-#include "basic-block.h"
#include "tree-ssanames.h"
#include "tree-dfa.h"
#include "value-prof.h"
&& (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
return c_strlen (TREE_OPERAND (src, 1), only_value);
- loc = EXPR_LOC_OR_HERE (src);
+ loc = EXPR_LOC_OR_LOC (src, input_location);
src = string_constant (src, &offset_node);
if (src == 0)
}
else if (range_type == VR_ANTI_RANGE)
{
- /* Anti range 0...N lets us to determine minmal size to N+1. */
+ /* Anti range 0...N lets us to determine minimal size to N+1. */
if (min == 0)
{
if (wi::fits_uhwi_p (max) && max.to_uhwi () + 1 != 0)
int n;
if (n < 100)
- memcpy (a,b, n)
+ memcpy (a, b, n)
Produce anti range allowing negative values of N. We still
can use the information and make a guess that N is not negative.
&& fcode != BUILT_IN_EXECVE
&& fcode != BUILT_IN_ALLOCA
&& fcode != BUILT_IN_ALLOCA_WITH_ALIGN
- && fcode != BUILT_IN_FREE
- && fcode != BUILT_IN_CHKP_SET_PTR_BOUNDS
- && fcode != BUILT_IN_CHKP_INIT_PTR_BOUNDS
- && fcode != BUILT_IN_CHKP_NULL_PTR_BOUNDS
- && fcode != BUILT_IN_CHKP_COPY_PTR_BOUNDS
- && fcode != BUILT_IN_CHKP_NARROW_PTR_BOUNDS
- && fcode != BUILT_IN_CHKP_STORE_PTR_BOUNDS
- && fcode != BUILT_IN_CHKP_CHECK_PTR_LBOUNDS
- && fcode != BUILT_IN_CHKP_CHECK_PTR_UBOUNDS
- && fcode != BUILT_IN_CHKP_CHECK_PTR_BOUNDS
- && fcode != BUILT_IN_CHKP_GET_PTR_LBOUND
- && fcode != BUILT_IN_CHKP_GET_PTR_UBOUND)
+ && fcode != BUILT_IN_FREE)
return expand_call (exp, target, ignore);
/* The built-in function expanders test for target == const0_rtx
expand_builtin_cilk_pop_frame (exp);
return const0_rtx;
- case BUILT_IN_CHKP_INIT_PTR_BOUNDS:
- case BUILT_IN_CHKP_NULL_PTR_BOUNDS:
- case BUILT_IN_CHKP_COPY_PTR_BOUNDS:
- return expand_normal (CALL_EXPR_ARG (exp, 0));
-
- case BUILT_IN_CHKP_CHECK_PTR_LBOUNDS:
- case BUILT_IN_CHKP_CHECK_PTR_UBOUNDS:
- case BUILT_IN_CHKP_CHECK_PTR_BOUNDS:
- case BUILT_IN_CHKP_SET_PTR_BOUNDS:
- case BUILT_IN_CHKP_NARROW_PTR_BOUNDS:
- case BUILT_IN_CHKP_STORE_PTR_BOUNDS:
- case BUILT_IN_CHKP_GET_PTR_LBOUND:
- case BUILT_IN_CHKP_GET_PTR_UBOUND:
- /* We allow user CHKP builtins if Pointer Bounds
- Checker is off. */
- if (!flag_check_pointer_bounds)
- {
- if (fcode == BUILT_IN_CHKP_SET_PTR_BOUNDS
- || fcode == BUILT_IN_CHKP_NARROW_PTR_BOUNDS)
- return expand_normal (CALL_EXPR_ARG (exp, 0));
- else if (fcode == BUILT_IN_CHKP_GET_PTR_LBOUND)
- return expand_normal (size_zero_node);
- else if (fcode == BUILT_IN_CHKP_GET_PTR_UBOUND)
- return expand_normal (size_int (-1));
- else
- return const0_rtx;
- }
- /* FALLTHROUGH */
-
- case BUILT_IN_CHKP_BNDMK:
- case BUILT_IN_CHKP_BNDSTX:
- case BUILT_IN_CHKP_BNDCL:
- case BUILT_IN_CHKP_BNDCU:
- case BUILT_IN_CHKP_BNDLDX:
- case BUILT_IN_CHKP_BNDRET:
- case BUILT_IN_CHKP_INTERSECT:
- case BUILT_IN_CHKP_ARG_BND:
- case BUILT_IN_CHKP_NARROW:
- case BUILT_IN_CHKP_EXTRACT_LOWER:
- case BUILT_IN_CHKP_EXTRACT_UPPER:
- /* Software implementation of pointers checker is NYI.
- Target support is required. */
- error ("Your target platform does not support -fcheck-pointers");
- break;
-
default: /* just do library call, if unknown builtin */
break;
}
DEF_BUILTIN (ENUM, NAME, BUILT_IN_NORMAL, BT_FN_INT_VAR, BT_LAST, \
false, false, false, ATTRS, false, flag_enable_cilkplus)
-/* Builtin used by the implementation of Pointer Bounds Checker. */
-#undef DEF_CHKP_BUILTIN
-#define DEF_CHKP_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
- DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
- true, true, false, ATTRS, true, true)
-
/* Define an attribute list for math functions that are normally
"impure" because some of them may write into global memory for
`errno'. If !flag_errno_math they are instead "const". */
/* Cilk Plus builtins. */
#include "cilkplus.def"
-
-/* Pointer Bounds Checker builtins. */
-#include "chkp-builtins.def"
+2013-11-29 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR c/59309
+ * cilk.c (gimplify_cilk_spawn): Properly handle function without
+ arguments.
+
+2013-11-29 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/59280
+ * c-common.c (get_priority): If TREE_VALUE (args) is IDENTIFIER_NODE,
+ goto invalid. If it is error_mark_node, don't issue further
+ diagnostics.
+
+2013-11-28 Sergey Ostanevich <sergos.gnu@gmail.com>
+
+ * c.opt (Wopenmp-simd): New.
+
+2013-11-22 Jakub Jelinek <jakub@redhat.com>
+
+ * c-ubsan.h (ubsan_instrument_return): New prototype.
+ * c-ubsan.c (ubsan_instrument_return): New function.
+
+2013-11-22 Andrew MacLeod <amacleod@redhat.com>
+
+ * c-common.c: Add required include files from gimple.h.
+ * c-gimplify.c: Likewise
+ * cilk.c: Likewise
+
+2013-11-22 David Malcolm <dmalcolm@redhat.com>
+
+ * c-common.c (unsafe_conversion_p): Remove use of
+ EXPR_LOC_OR_HERE macro.
+ (conversion_warning): Likewise.
+ (warnings_for_convert_and_check): Likewise.
+ (warn_for_collisions_1): Likewise.
+ (shorten_compare): Likewise, and remove use of in_system_header
+ macro, using the location from the former.
+ * c-lex.c (dump_one_header): Remove use of input_filename macro.
+ (cb_def_pragma): Remove use of in_system_header macro.
+ (lex_string): Likewise.
+ * c-pragma.c (handle_pragma_float_const_decimal64): Likewise.
+
2013-11-20 Kenneth Zadeck <zadeck@naturalbridge.com>
Mike Stump <mikestump@comcast.net>
Richard Sandiford <rdsandiford@googlemail.com>
#include "trans-mem.h"
#include "flags.h"
#include "c-pragma.h"
-#include "ggc.h"
#include "c-common.h"
#include "c-objc.h"
#include "tm_p.h"
#include "opts.h"
#include "cgraph.h"
#include "target-def.h"
-#include "gimple.h"
#include "gimplify.h"
#include "wide-int-print.h"
bool *);
static tree handle_omp_declare_target_attribute (tree *, tree, tree, int,
bool *);
-static tree handle_bnd_variable_size_attribute (tree *, tree, tree, int, bool *);
-static tree handle_bnd_legacy (tree *, tree, tree, int, bool *);
static void check_function_nonnull (tree, int, tree *);
static void check_nonnull_arg (void *, tree, unsigned HOST_WIDE_INT);
handle_omp_declare_simd_attribute, false },
{ "omp declare target", 0, 0, true, false, false,
handle_omp_declare_target_attribute, false },
- { "bnd_variable_size", 0, 0, true, false, false,
- handle_bnd_variable_size_attribute, false },
- { "bnd_legacy", 0, 0, true, false, false,
- handle_bnd_legacy, false },
{ NULL, 0, 0, false, false, false, NULL, false }
};
{
enum conversion_safety give_warning = SAFE_CONVERSION; /* is 0 or false */
tree expr_type = TREE_TYPE (expr);
- location_t loc = EXPR_LOC_OR_HERE (expr);
+ location_t loc = EXPR_LOC_OR_LOC (expr, input_location);
if (TREE_CODE (expr) == REAL_CST || TREE_CODE (expr) == INTEGER_CST)
{
conversion_warning (tree type, tree expr)
{
tree expr_type = TREE_TYPE (expr);
- location_t loc = EXPR_LOC_OR_HERE (expr);
+ location_t loc = EXPR_LOC_OR_LOC (expr, input_location);
enum conversion_safety conversion_kind;
if (!warn_conversion && !warn_sign_conversion && !warn_float_conversion)
void
warnings_for_convert_and_check (tree type, tree expr, tree result)
{
- location_t loc = EXPR_LOC_OR_HERE (expr);
+ location_t loc = EXPR_LOC_OR_LOC (expr, input_location);
if (TREE_CODE (expr) == INTEGER_CST
&& (TREE_CODE (type) == INTEGER_TYPE
&& (!only_writes || list->writer))
{
warned_ids = new_tlist (warned_ids, written, NULL_TREE);
- warning_at (EXPR_LOC_OR_HERE (writer),
+ warning_at (EXPR_LOC_OR_LOC (writer, input_location),
OPT_Wsequence_point, "operation on %qE may be undefined",
list->expr);
}
int real1, real2;
tree primop0, primop1;
enum tree_code code = *rescode_ptr;
- location_t loc = EXPR_LOC_OR_HERE (op0);
+ location_t loc = EXPR_LOC_OR_LOC (op0, input_location);
/* Throw away any conversions to wider types
already present in the operands. */
the comparison isn't an issue, so suppress the
warning. */
bool warn =
- warn_type_limits && !in_system_header
+ warn_type_limits && !in_system_header_at (loc)
&& c_inhibit_evaluation_warnings == 0
&& !(TREE_CODE (primop0) == INTEGER_CST
&& !TREE_OVERFLOW (convert (c_common_signed_type (type),
}
arg = TREE_VALUE (args);
+ if (TREE_CODE (arg) == IDENTIFIER_NODE)
+ goto invalid;
+ if (arg == error_mark_node)
+ return DEFAULT_INIT_PRIORITY;
arg = default_conversion (arg);
if (!tree_fits_shwi_p (arg)
|| !INTEGRAL_TYPE_P (TREE_TYPE (arg)))
return NULL_TREE;
}
-/* Handle a "bnd_variable_size" attribute; arguments as in
- struct attribute_spec.handler. */
-
-static tree
-handle_bnd_variable_size_attribute (tree *node, tree name, tree ARG_UNUSED (args),
- int ARG_UNUSED (flags), bool *no_add_attrs)
-{
- if (TREE_CODE (*node) != FIELD_DECL)
- {
- warning (OPT_Wattributes, "%qE attribute ignored", name);
- *no_add_attrs = true;
- }
-
- return NULL_TREE;
-}
-
-/* Handle a "bnd_legacy" attribute; arguments as in
- struct attribute_spec.handler. */
-
-static tree
-handle_bnd_legacy (tree *node, tree name, tree ARG_UNUSED (args),
- int ARG_UNUSED (flags), bool *no_add_attrs)
-{
- if (TREE_CODE (*node) != FUNCTION_DECL)
- {
- warning (OPT_Wattributes, "%qE attribute ignored", name);
- *no_add_attrs = true;
- }
-
- return NULL_TREE;
-}
-
/* Handle a "warn_unused" attribute; arguments as in
struct attribute_spec.handler. */
#include "tm.h"
#include "tree.h"
#include "c-common.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimplify.h"
#include "tree-inline.h"
void
dump_time_statistics (void)
{
- struct c_fileinfo *file = get_fileinfo (input_filename);
+ struct c_fileinfo *file = get_fileinfo (LOCATION_FILE (input_location));
int this_time = get_run_time ();
file->time += this_time - body_time;
/* Issue a warning message if we have been asked to do so. Ignore
unknown pragmas in system headers unless an explicit
-Wunknown-pragmas has been given. */
- if (warn_unknown_pragmas > in_system_header)
+ if (warn_unknown_pragmas > in_system_header_at (input_location))
{
const unsigned char *space, *name;
const cpp_token *s;
if (concats)
strs = XOBFINISH (&str_ob, cpp_string *);
- if (concats && !objc_string && !in_system_header)
+ if (concats && !objc_string && !in_system_header_at (input_location))
warning (OPT_Wtraditional,
"traditional C rejects string constant concatenation");
{
if (c_dialect_cxx ())
{
- if (warn_unknown_pragmas > in_system_header)
+ if (warn_unknown_pragmas > in_system_header_at (input_location))
warning (OPT_Wunknown_pragmas,
"%<#pragma STDC FLOAT_CONST_DECIMAL64%> is not supported"
" for C++");
if (!targetm.decimal_float_supported_p ())
{
- if (warn_unknown_pragmas > in_system_header)
+ if (warn_unknown_pragmas > in_system_header_at (input_location))
warning (OPT_Wunknown_pragmas,
"%<#pragma STDC FLOAT_CONST_DECIMAL64%> is not supported"
" on this target");
return t;
}
+
+/* Instrument missing return in C++ functions returning non-void. */
+
+tree
+ubsan_instrument_return (location_t loc)
+{
+ tree data = ubsan_create_data ("__ubsan_missing_return_data", loc,
+ NULL, NULL_TREE);
+ tree t = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_MISSING_RETURN);
+ return build_call_expr_loc (loc, t, 1, build_fold_addr_expr_loc (loc, data));
+}
extern tree ubsan_instrument_division (location_t, tree, tree);
extern tree ubsan_instrument_shift (location_t, enum tree_code, tree, tree);
extern tree ubsan_instrument_vla (location_t, tree);
+extern tree ubsan_instrument_return (location_t);
#endif /* GCC_C_UBSAN_H */
C ObjC Var(warn_old_style_definition) Warning
Warn if an old-style parameter definition is used
+Wopenmp-simd
+C C++ Var(warn_openmp_simd) Warning LangEnabledBy(C C++,Wall)
+Warn if a simd directive is overridden by the vectorizer cost model
+
Woverlength-strings
C ObjC C++ ObjC++ Var(warn_overlength_strings) Warning LangEnabledBy(C ObjC C++ ObjC++,Wpedantic)
Warn if a string is longer than the maximum portable length specified by the standard
C ObjC C++ ObjC++
Where shorter, use canonicalized paths to systems headers.
-fcheck-pointer-bounds
-C ObjC C++ ObjC++ LTO Report Var(flag_check_pointer_bounds)
-Add Pointer Bounds Checker instrumentation. fchkp-* flags are used to
-control instrumentation.
-
fcilkplus
C ObjC C++ ObjC++ LTO Report Var(flag_enable_cilkplus) Init(0)
Enable Cilk Plus
#include "stringpool.h"
#include "calls.h"
#include "langhooks.h"
-#include "gimple.h"
+#include "pointer-set.h"
+#include "gimple-expr.h"
#include "gimplify.h"
#include "tree-iterator.h"
#include "tree-inline.h"
/* This should give the number of parameters. */
total_args = list_length (new_args);
- arg_array = XNEWVEC (tree, total_args);
+ if (total_args)
+ arg_array = XNEWVEC (tree, total_args);
+ else
+ arg_array = NULL;
ii_args = new_args;
for (ii = 0; ii < total_args; ii++)
call1 = cilk_call_setjmp (cfun->cilk_frame_decl);
- if (*arg_array == NULL_TREE)
+ if (arg_array == NULL || *arg_array == NULL_TREE)
call2 = build_call_expr (function, 0);
else
call2 = build_call_expr_loc_array (EXPR_LOCATION (*spawn_p), function,
+2013-12-03 Marek Polacek <polacek@redhat.com>
+
+ PR c/59351
+ * c-decl.c (build_compound_literal): Allow compound literals with
+ empty initial value.
+
+2013-12-02 Joseph Myers <joseph@codesourcery.com>
+
+ PR c/58235
+ * c-typeck.c (build_modify_expr): Diagnose assignment to
+ expression with array type.
+
+2013-11-29 Joseph Myers <joseph@codesourcery.com>
+
+ PR c/42262
+ * c-typeck.c (process_init_element): Do not treat a string as
+ initializing a whole array when used with a designator for an
+ individual element.
+
+2013-11-29 Joseph Myers <joseph@codesourcery.com>
+
+ PR c/57574
+ * c-decl.c (merge_decls): Clear DECL_EXTERNAL for a definition of
+ an inline function following a static declaration.
+
+2013-11-28 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/59310
+ * c-parser.c (c_parser_omp_target): Copy "#pragma omp target"
+ to p_name before calling c_parser_omp_teams instead of after.
+ (c_parser_cilk_simd): Remove wrong ATTRIBUTE_UNUSED from parser
+ argument. Remove unused p_name variable.
+
+2013-11-27 Aldy Hernandez <aldyh@redhat.com>
+ Jakub Jelinek <jakub@redhat.com>
+
+ * c-decl.c (c_builtin_function_ext_scope): Avoid binding if
+ external_scope is NULL.
+
+2013-11-27 Tom de Vries <tom@codesourcery.com>
+ Marc Glisse <marc.glisse@inria.fr>
+
+ PR c++/59032
+ * c-typeck.c (build_unary_op): Allow vector increment and decrement.
+
+2013-11-22 Andrew MacLeod <amacleod@redhat.com>
+
+ * c-typeck.c: Add required include files from gimple.h.
+
+2013-11-22 David Malcolm <dmalcolm@redhat.com>
+
+ * c-decl.c (define_label, shadow_tag_warned)
+ (check_bitfield_type_and_width, grokdeclarator, grokparms,
+ store_parm_decls_newstyle, store_parm_decls_oldstyle)
+ (declspecs_add_type): Remove use of in_system_header macro.
+ * c-parser.c (c_parser_unary_expression): Likewise.
+ * c-typeck.c (store_init_value, process_init_element)
+ (c_start_case): Likewise.
+
+ * c-decl.c (build_enumerator): Remove use of EXPR_LOC_OR_HERE
+ macro.
+
+ * c-parser.c (c_parser_set_source_position_from_token): Remove
+ reference to in_system_header from comment.
+
2013-11-18 Richard Sandiford <rdsandiford@googlemail.com>
* c-decl.c (grokdeclarator): Update comment to refer to
&& !current_function_decl)
DECL_EXTERNAL (newdecl) = 0;
+ /* An inline definition following a static declaration is not
+ DECL_EXTERNAL. */
+ if (new_is_definition
+ && (DECL_DECLARED_INLINE_P (newdecl)
+ || DECL_DECLARED_INLINE_P (olddecl))
+ && !TREE_PUBLIC (olddecl))
+ DECL_EXTERNAL (newdecl) = 0;
+
if (DECL_EXTERNAL (newdecl))
{
TREE_STATIC (newdecl) = TREE_STATIC (olddecl);
bind_label (name, label, current_function_scope, label_vars);
}
- if (!in_system_header && lookup_name (name))
+ if (!in_system_header_at (input_location) && lookup_name (name))
warning_at (location, OPT_Wtraditional,
"traditional C lacks a separate namespace "
"for labels, identifier %qE conflicts", name);
const char *name = IDENTIFIER_POINTER (id);
C_DECL_BUILTIN_PROTOTYPE (decl) = prototype_p (type);
- bind (id, decl, external_scope, /*invisible=*/false, /*nested=*/false,
- UNKNOWN_LOCATION);
+ if (external_scope)
+ bind (id, decl, external_scope, /*invisible=*/false, /*nested=*/false,
+ UNKNOWN_LOCATION);
/* Builtins in the implementation namespace are made visible without
needing to be explicitly declared. See push_file_scope. */
}
else
{
- if (warned != 1 && !in_system_header)
+ if (warned != 1 && !in_system_header_at (input_location))
{
pedwarn (input_location, 0,
"useless type name in empty declaration");
}
}
}
- else if (warned != 1 && !in_system_header && declspecs->typedef_p)
+ else if (warned != 1 && !in_system_header_at (input_location)
+ && declspecs->typedef_p)
{
pedwarn (input_location, 0, "useless type name in empty declaration");
warned = 1;
warned = 1;
}
- if (!warned && !in_system_header && declspecs->storage_class != csc_none)
+ if (!warned && !in_system_header_at (input_location)
+ && declspecs->storage_class != csc_none)
{
warning (0, "useless storage class specifier in empty declaration");
warned = 2;
}
- if (!warned && !in_system_header && declspecs->thread_p)
+ if (!warned && !in_system_header_at (input_location) && declspecs->thread_p)
{
warning (0, "useless %qs in empty declaration",
declspecs->thread_gnu_p ? "__thread" : "_Thread_local");
warned = 2;
}
- if (!warned && !in_system_header && (declspecs->const_p
- || declspecs->volatile_p
- || declspecs->atomic_p
- || declspecs->restrict_p
- || declspecs->address_space))
+ if (!warned
+ && !in_system_header_at (input_location)
+ && (declspecs->const_p
+ || declspecs->volatile_p
+ || declspecs->atomic_p
+ || declspecs->restrict_p
+ || declspecs->address_space))
{
warning (0, "useless type qualifier in empty declaration");
warned = 2;
}
- if (!warned && !in_system_header && declspecs->alignas_p)
+ if (!warned && !in_system_header_at (input_location)
+ && declspecs->alignas_p)
{
warning (0, "useless %<_Alignas%> in empty declaration");
warned = 2;
{
int failure = complete_array_type (&TREE_TYPE (decl),
DECL_INITIAL (decl), true);
- gcc_assert (!failure);
+ /* If complete_array_type returns 3, it means that the
+ initial value of the compound literal is empty. Allow it. */
+ gcc_assert (failure == 0 || failure == 3);
type = TREE_TYPE (decl);
TREE_TYPE (DECL_INITIAL (decl)) = type;
}
type_mv = TYPE_MAIN_VARIANT (*type);
- if (!in_system_header
+ if (!in_system_header_at (input_location)
&& type_mv != integer_type_node
&& type_mv != unsigned_type_node
&& type_mv != boolean_type_node)
/* Diagnose defaulting to "int". */
- if (declspecs->default_int_p && !in_system_header)
+ if (declspecs->default_int_p && !in_system_header_at (input_location))
{
/* Issue a warning if this is an ISO C 99 program or if
-Wreturn-type and this is a function, or if -Wimplicit;
type = error_mark_node;
}
- if (pedantic && !in_system_header && flexible_array_type_p (type))
+ if (pedantic && !in_system_header_at (input_location)
+ && flexible_array_type_p (type))
pedwarn (loc, OPT_Wpedantic,
"invalid use of structure with flexible array member");
flexible_array_member = (t->kind == cdk_id);
}
if (flexible_array_member
- && pedantic && !flag_isoc99 && !in_system_header)
+ && pedantic && !flag_isoc99
+ && !in_system_header_at (input_location))
pedwarn (loc, OPT_Wpedantic,
"ISO C90 does not support flexible array members");
error ("%<[*]%> not allowed in other than function prototype scope");
}
- if (arg_types == 0 && !funcdef_flag && !in_system_header)
+ if (arg_types == 0 && !funcdef_flag
+ && !in_system_header_at (input_location))
warning (OPT_Wstrict_prototypes,
"function declaration isn%'t a prototype");
/* Set basis for default for next value. */
the_enum->enum_next_value
- = build_binary_op (EXPR_LOC_OR_HERE (value),
+ = build_binary_op (EXPR_LOC_OR_LOC (value, input_location),
PLUS_EXPR, value, integer_one_node, 0);
the_enum->enum_overflow = tree_int_cst_lt (the_enum->enum_next_value, value);
warning if we got here because ARG_INFO_TYPES was error_mark_node
(this happens when a function definition has just an ellipsis in
its parameter list). */
- else if (!in_system_header && !current_function_scope
+ else if (!in_system_header_at (input_location)
+ && !current_function_scope
&& arg_info->types != error_mark_node)
warning_at (DECL_SOURCE_LOCATION (fndecl), OPT_Wtraditional,
"traditional C rejects ISO C style function definitions");
tree parmids = arg_info->parms;
struct pointer_set_t *seen_args = pointer_set_create ();
- if (!in_system_header)
+ if (!in_system_header_at (input_location))
warning_at (DECL_SOURCE_LOCATION (fndecl),
OPT_Wold_style_definition, "old-style function definition");
error_at (loc, "%<__int128%> is not supported for this target");
return specs;
}
- if (!in_system_header)
+ if (!in_system_header_at (input_location))
pedwarn (loc, OPT_Wpedantic,
"ISO C does not support %<__int128%> type");
parser->in_pragma = true;
}
-/* Update the globals input_location and in_system_header from
- TOKEN. */
+/* Update the global input_location from TOKEN. */
static inline void
c_parser_set_source_position_from_token (c_token *token)
{
ret.value = build_indirect_ref (op_loc, op.value, RO_UNARY_STAR);
return ret;
case CPP_PLUS:
- if (!c_dialect_objc () && !in_system_header)
+ if (!c_dialect_objc () && !in_system_header_at (input_location))
warning_at (op_loc,
OPT_Wtraditional,
"traditional C rejects the unary plus operator");
"parallel for simd")];
c_parser_consume_token (parser);
+ strcpy (p_name, "#pragma omp target");
if (!flag_openmp) /* flag_openmp_simd */
return c_parser_omp_teams (loc, parser, p_name,
OMP_TARGET_CLAUSE_MASK, cclauses);
- strcpy (p_name, "#pragma omp target");
keep_next_level ();
tree block = c_begin_compound_stmt (true);
tree ret = c_parser_omp_teams (loc, parser, p_name,
loops. */
static void
-c_parser_cilk_simd (c_parser *parser ATTRIBUTE_UNUSED)
+c_parser_cilk_simd (c_parser *parser)
{
- char p_name[100];
- strcpy (p_name, "#pragma omp");
tree clauses = c_parser_cilk_all_clauses (parser);
tree block = c_begin_compound_stmt (true);
location_t loc = c_parser_peek_token (parser)->location;
#include "target.h"
#include "tree-iterator.h"
#include "bitmap.h"
-#include "gimple.h"
+#include "pointer-set.h"
+#include "basic-block.h"
+#include "gimple-expr.h"
#include "gimplify.h"
#include "tree-inline.h"
#include "omp-low.h"
if (typecode != POINTER_TYPE && typecode != FIXED_POINT_TYPE
&& typecode != INTEGER_TYPE && typecode != REAL_TYPE
- && typecode != COMPLEX_TYPE)
+ && typecode != COMPLEX_TYPE && typecode != VECTOR_TYPE)
{
if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
error_at (location, "wrong type argument to increment");
}
else
{
- inc = integer_one_node;
+ inc = VECTOR_TYPE_P (argtype)
+ ? build_one_cst (argtype)
+ : integer_one_node;
inc = convert (argtype, inc);
}
if (TREE_CODE (lhs) == ERROR_MARK || TREE_CODE (rhs) == ERROR_MARK)
return error_mark_node;
+ /* Ensure an error for assigning a non-lvalue array to an array in
+ C90. */
+ if (TREE_CODE (lhstype) == ARRAY_TYPE)
+ {
+ error_at (location, "assignment to expression with array type");
+ return error_mark_node;
+ }
+
/* For ObjC properties, defer this check. */
if (!objc_is_property_ref (lhs) && !lvalue_or_else (location, lhs, lv_assign))
return error_mark_node;
/* Store the expression if valid; else report error. */
- if (!in_system_header
+ if (!in_system_header_at (input_location)
&& AGGREGATE_TYPE_P (TREE_TYPE (decl)) && !TREE_STATIC (decl))
warning (OPT_Wtraditional, "traditional C rejects automatic "
"aggregate initialization");
tree orig_value = value.value;
int string_flag = orig_value != 0 && TREE_CODE (orig_value) == STRING_CST;
bool strict_string = value.original_code == STRING_CST;
+ bool was_designated = designator_depth != 0;
designator_depth = 0;
designator_erroneous = 0;
char x[] = {"foo"}; */
if (string_flag
&& constructor_type
+ && !was_designated
&& TREE_CODE (constructor_type) == ARRAY_TYPE
&& INTEGRAL_TYPE_P (TREE_TYPE (constructor_type))
&& integer_zerop (constructor_unfilled_index))
again on the assumption that this must be conditional on
__STDC__ anyway (and we've already complained about the
member-designator already). */
- if (!in_system_header && !constructor_designated
+ if (!in_system_header_at (input_location) && !constructor_designated
&& !(value.value && (integer_zerop (value.value)
|| real_zerop (value.value))))
warning (OPT_Wtraditional, "traditional C rejects initialization "
{
tree type = TYPE_MAIN_VARIANT (orig_type);
- if (!in_system_header
+ if (!in_system_header_at (input_location)
&& (type == long_integer_type_node
|| type == long_unsigned_type_node))
warning_at (switch_cond_loc,
#include "varasm.h"
#include "stringpool.h"
#include "attribs.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "flags.h"
#include "expr.h"
recursion "call". That way we know any adjustment after the tail
recursion call can be ignored if we indeed use the tail
call expansion. */
- int save_pending_stack_adjust = 0;
- int save_stack_pointer_delta = 0;
+ saved_pending_stack_adjust save;
rtx insns;
rtx before_call, next_arg_reg, after_args;
{
/* State variables we need to save and restore between
iterations. */
- save_pending_stack_adjust = pending_stack_adjust;
- save_stack_pointer_delta = stack_pointer_delta;
+ save_pending_stack_adjust (&save);
}
if (pass)
flags &= ~ECF_SIBCALL;
{
rtx before_arg = get_last_insn ();
+ /* We don't allow passing huge (> 2^30 B) arguments
+ by value. It would cause an overflow later on. */
+ if (adjusted_args_size.constant
+ >= (1 << (HOST_BITS_PER_INT - 2)))
+ {
+ sorry ("passing too large argument on stack");
+ continue;
+ }
+
if (store_one_arg (&args[i], argblock, flags,
adjusted_args_size.var != 0,
reg_parm_stack_space)
/* Restore the pending stack adjustment now that we have
finished generating the sibling call sequence. */
- pending_stack_adjust = save_pending_stack_adjust;
- stack_pointer_delta = save_stack_pointer_delta;
+ restore_pending_stack_adjust (&save);
/* Prepare arg structure for next iteration. */
for (i = 0; i < num_actuals; i++)
#include "expr.h"
#include "langhooks.h"
#include "bitmap.h"
+#include "pointer-set.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimple-walk.h"
/* Vector of partition representative decls in between the paddings. */
vec<tree> asan_decl_vec;
+
+ /* Base pseudo register for Address Sanitizer protected automatic vars. */
+ rtx asan_base;
+
+ /* Alignment needed for the Address Sanitizer protected automatic vars. */
+ unsigned int asan_alignb;
};
/* A subroutine of expand_used_vars. Give each partition representative
alignb = stack_vars[i].alignb;
if (alignb * BITS_PER_UNIT <= MAX_SUPPORTED_STACK_ALIGNMENT)
{
+ base = virtual_stack_vars_rtx;
if ((flag_sanitize & SANITIZE_ADDRESS) && pred)
{
HOST_WIDE_INT prev_offset = frame_offset;
if (repr_decl == NULL_TREE)
repr_decl = stack_vars[i].decl;
data->asan_decl_vec.safe_push (repr_decl);
+ data->asan_alignb = MAX (data->asan_alignb, alignb);
+ if (data->asan_base == NULL)
+ data->asan_base = gen_reg_rtx (Pmode);
+ base = data->asan_base;
}
else
offset = alloc_stack_frame_space (stack_vars[i].size, alignb);
- base = virtual_stack_vars_rtx;
base_align = crtl->max_used_stack_slot_alignment;
}
else
data.asan_vec = vNULL;
data.asan_decl_vec = vNULL;
+ data.asan_base = NULL_RTX;
+ data.asan_alignb = 0;
/* Reorder decls to be protected by iterating over the variables
array multiple times, and allocating out of each phase in turn. */
if (!data.asan_vec.is_empty ())
{
HOST_WIDE_INT prev_offset = frame_offset;
- HOST_WIDE_INT offset
- = alloc_stack_frame_space (ASAN_RED_ZONE_SIZE,
- ASAN_RED_ZONE_SIZE);
+ HOST_WIDE_INT offset, sz, redzonesz;
+ redzonesz = ASAN_RED_ZONE_SIZE;
+ sz = data.asan_vec[0] - prev_offset;
+ if (data.asan_alignb > ASAN_RED_ZONE_SIZE
+ && data.asan_alignb <= 4096
+ && sz + ASAN_RED_ZONE_SIZE >= (int) data.asan_alignb)
+ redzonesz = ((sz + ASAN_RED_ZONE_SIZE + data.asan_alignb - 1)
+ & ~(data.asan_alignb - HOST_WIDE_INT_1)) - sz;
+ offset
+ = alloc_stack_frame_space (redzonesz, ASAN_RED_ZONE_SIZE);
data.asan_vec.safe_push (prev_offset);
data.asan_vec.safe_push (offset);
var_end_seq
= asan_emit_stack_protection (virtual_stack_vars_rtx,
+ data.asan_base,
+ data.asan_alignb,
data.asan_vec.address (),
- data.asan_decl_vec. address (),
+ data.asan_decl_vec.address (),
data.asan_vec.length ());
}
return;
}
- decl = gimple_call_fndecl (stmt);
- builtin_p = decl && DECL_BUILT_IN (decl);
-
- /* Bind bounds call is expanded as assignment. */
- if (builtin_p
- && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL
- && DECL_FUNCTION_CODE (decl) == BUILT_IN_CHKP_BIND_BOUNDS)
- {
- expand_assignment (gimple_call_lhs (stmt),
- gimple_call_arg (stmt, 0), false);
- return;
- }
-
exp = build_vl_exp (CALL_EXPR, gimple_call_num_args (stmt) + 3);
+
CALL_EXPR_FN (exp) = gimple_call_fn (stmt);
+ decl = gimple_call_fndecl (stmt);
+ builtin_p = decl && DECL_BUILT_IN (decl);
/* If this is not a builtin function, the function type through which the
call is made may be different from the type of the function. */
#include "diagnostic-core.h"
#include "flags.h"
#include "tree.h"
+#include "pointer-set.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimple-ssa.h"
-#include "pointer-set.h"
-#include "ggc.h"
#include "dumpfile.h"
static void flow_loops_cfg_dump (FILE *);
#include "basic-block.h"
#include "cfgloop.h"
#include "tree.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimplify-me.h"
#include "hashtab.h"
#include "toplev.h"
#include "flags.h"
-#include "ggc.h"
#include "debug.h"
#include "target.h"
-#include "basic-block.h"
#include "cgraph.h"
#include "intl.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "timevar.h"
{
new_stmt = e->call_stmt;
gimple_call_set_fndecl (new_stmt, e->callee->decl);
- update_stmt (new_stmt);
+ update_stmt_fn (DECL_STRUCT_FUNCTION (e->caller->decl), new_stmt);
}
cgraph_set_call_stmt_including_clones (e->caller, e->call_stmt, new_stmt, false);
bitmap combined_args_to_skip;
};
+enum cgraph_simd_clone_arg_type
+{
+ SIMD_CLONE_ARG_TYPE_VECTOR,
+ SIMD_CLONE_ARG_TYPE_UNIFORM,
+ SIMD_CLONE_ARG_TYPE_LINEAR_CONSTANT_STEP,
+ SIMD_CLONE_ARG_TYPE_LINEAR_VARIABLE_STEP,
+ SIMD_CLONE_ARG_TYPE_MASK
+};
+
+/* Function arguments in the original function of a SIMD clone.
+ Supplementary data for `struct simd_clone'. */
+
+struct GTY(()) cgraph_simd_clone_arg {
+ /* Original function argument as it originally existed in
+ DECL_ARGUMENTS. */
+ tree orig_arg;
+
+ /* orig_arg's function (or for extern functions type from
+ TYPE_ARG_TYPES). */
+ tree orig_type;
+
+ /* If argument is a vector, this holds the vector version of
+ orig_arg that after adjusting the argument types will live in
+ DECL_ARGUMENTS. Otherwise, this is NULL.
+
+ This basically holds:
+ vector(simdlen) __typeof__(orig_arg) new_arg. */
+ tree vector_arg;
+
+ /* vector_arg's type (or for extern functions new vector type. */
+ tree vector_type;
+
+ /* If argument is a vector, this holds the array where the simd
+ argument is held while executing the simd clone function. This
+ is a local variable in the cloned function. Its content is
+ copied from vector_arg upon entry to the clone.
+
+ This basically holds:
+ __typeof__(orig_arg) simd_array[simdlen]. */
+ tree simd_array;
+
+ /* A SIMD clone's argument can be either linear (constant or
+ variable), uniform, or vector. */
+ enum cgraph_simd_clone_arg_type arg_type;
+
+ /* For arg_type SIMD_CLONE_ARG_TYPE_LINEAR_CONSTANT_STEP this is
+ the constant linear step, if arg_type is
+ SIMD_CLONE_ARG_TYPE_LINEAR_VARIABLE_STEP, this is index of
+ the uniform argument holding the step, otherwise 0. */
+ HOST_WIDE_INT linear_step;
+
+ /* Variable alignment if available, otherwise 0. */
+ unsigned int alignment;
+};
+
+/* Specific data for a SIMD function clone. */
+
+struct GTY(()) cgraph_simd_clone {
+ /* Number of words in the SIMD lane associated with this clone. */
+ unsigned int simdlen;
+
+ /* Number of annotated function arguments in `args'. This is
+ usually the number of named arguments in FNDECL. */
+ unsigned int nargs;
+
+ /* Max hardware vector size in bits for integral vectors. */
+ unsigned int vecsize_int;
+
+ /* Max hardware vector size in bits for floating point vectors. */
+ unsigned int vecsize_float;
+
+ /* The mangling character for a given vector size. This is is used
+ to determine the ISA mangling bit as specified in the Intel
+ Vector ABI. */
+ unsigned char vecsize_mangle;
+
+ /* True if this is the masked, in-branch version of the clone,
+ otherwise false. */
+ unsigned int inbranch : 1;
+
+ /* True if this is a Cilk Plus variant. */
+ unsigned int cilk_elemental : 1;
+
+ /* Doubly linked list of SIMD clones. */
+ struct cgraph_node *prev_clone, *next_clone;
+
+ /* Original cgraph node the SIMD clones were created for. */
+ struct cgraph_node *origin;
+
+ /* Annotated function arguments for the original function. */
+ struct cgraph_simd_clone_arg GTY((length ("%h.nargs"))) args[1];
+};
+
/* The cgraph data structure.
Each function decl has assigned cgraph_node listing callees and callers. */
/* Declaration node used to be clone of. */
tree former_clone_of;
+ /* If this is a SIMD clone, this points to the SIMD specific
+ information for it. */
+ struct cgraph_simd_clone *simdclone;
+ /* If this function has SIMD clones, this points to the first clone. */
+ struct cgraph_node *simd_clones;
+
/* Interprocedural passes scheduled to have their transform functions
applied next time we execute local pass on them. We maintain it
per-function in order to allow IPA passes to introduce new functions. */
/* Set when variable is scheduled to be assembled. */
unsigned output : 1;
- /* Set when variable has statically initialized pointer
- or is a static bounds variable and needs initalization. */
- unsigned need_bounds_init : 1;
+ /* Set if the variable is dynamically initialized, except for
+ function local statics. */
+ unsigned dynamically_initialized : 1;
};
/* Every top level asm statement is put into a asm_node. */
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
+#include "pointer-set.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-fold.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimple-walk.h"
#include "langhooks.h"
-#include "pointer-set.h"
#include "intl.h"
#include "tree-pass.h"
#include "ipa-utils.h"
if (decl)
cgraph_create_edge (node, cgraph_get_create_node (decl),
stmt, bb->count, freq);
+ else if (gimple_call_internal_p (stmt))
+ ;
else
cgraph_create_indirect_edge (node, stmt,
gimple_call_flags (stmt),
if (decl)
cgraph_create_edge (node, cgraph_get_create_node (decl), stmt,
bb->count, freq);
+ else if (gimple_call_internal_p (stmt))
+ ;
else
cgraph_create_indirect_edge (node, stmt,
gimple_call_flags (stmt),
#include "stringpool.h"
#include "function.h"
#include "emit-rtl.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "bitmap.h"
#include "tree-cfg.h"
#include "tree-inline.h"
#include "langhooks.h"
-#include "pointer-set.h"
#include "toplev.h"
#include "flags.h"
-#include "ggc.h"
#include "debug.h"
#include "target.h"
#include "diagnostic.h"
#include "stringpool.h"
#include "output.h"
#include "rtl.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-fold.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimplify.h"
#include "gimple-iterator.h"
#include "tree-ssa.h"
#include "tree-inline.h"
#include "langhooks.h"
-#include "pointer-set.h"
#include "toplev.h"
#include "flags.h"
-#include "ggc.h"
#include "debug.h"
#include "target.h"
#include "diagnostic.h"
+++ /dev/null
-/* This file contains the definitions and documentation for the
- builtins used in the GNU compiler.
- Copyright (C) 2013 Free Software Foundation, Inc.
-
-This file is part of GCC.
-
-GCC is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 3, or (at your option) any later
-version.
-
-GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-for more details.
-
-You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING3. If not see
-<http://www.gnu.org/licenses/>. */
-
-/* Before including this file, you should define macros:
-
- DEF_BUILTIN_STUB(ENUM, NAME)
- DEF_CHKP_BUILTIN(ENUM, NAME, TYPE, ATTRS)
-
- See builtins.def for details. */
-
-/* Following builtins are used by compiler for Pointer Bounds Checker
- instrumentation. Currently these generic builtins are not
- implemented and target has to provide his own version. See
- builtin_chkp_function target hook documentation for more details. */
-DEF_BUILTIN_STUB (BUILT_IN_CHKP_BNDMK, "__chkp_bndmk")
-DEF_BUILTIN_STUB (BUILT_IN_CHKP_BNDSTX, "__chkp_bndstx")
-DEF_BUILTIN_STUB (BUILT_IN_CHKP_BNDCL, "__chkp_bndcl")
-DEF_BUILTIN_STUB (BUILT_IN_CHKP_BNDCU, "__chkp_bndcu")
-DEF_BUILTIN_STUB (BUILT_IN_CHKP_BNDLDX, "__chkp_bndldx")
-DEF_BUILTIN_STUB (BUILT_IN_CHKP_BNDRET, "__chkp_bndret")
-DEF_BUILTIN_STUB (BUILT_IN_CHKP_INTERSECT, "__chkp_intersect")
-DEF_BUILTIN_STUB (BUILT_IN_CHKP_ARG_BND, "__chkp_arg_bnd")
-DEF_BUILTIN_STUB (BUILT_IN_CHKP_SIZEOF, "__chkp_sizeof")
-DEF_BUILTIN_STUB (BUILT_IN_CHKP_EXTRACT_LOWER, "__chkp_extract_lower")
-DEF_BUILTIN_STUB (BUILT_IN_CHKP_EXTRACT_UPPER, "__chkp_extract_upper")
-DEF_BUILTIN_STUB (BUILT_IN_CHKP_NARROW, "__chkp_narrow")
-
-/* Builtins to bind bounds to call arguments. */
-DEF_CHKP_BUILTIN (BUILT_IN_CHKP_BIND_BOUNDS, "__chkp_bind_bounds", BT_FN_PTR_CONST_PTR_VAR, ATTR_CONST_NOTHROW_LEAF_LIST)
-
-/* Pointer Bounds Checker builtins for users. Only
- BUILT_IN_CHKP_SET_PTR_BOUNDS may be redefined
- by target. Other builtins calls are expanded
- in the Pointer Bounds Checker pass. */
-DEF_CHKP_BUILTIN (BUILT_IN_CHKP_SET_PTR_BOUNDS, "__bnd_set_ptr_bounds", BT_FN_PTR_CONST_PTR_SIZE, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_CHKP_BUILTIN (BUILT_IN_CHKP_INIT_PTR_BOUNDS, "__bnd_init_ptr_bounds", BT_FN_PTR_CONST_PTR, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_CHKP_BUILTIN (BUILT_IN_CHKP_NULL_PTR_BOUNDS, "__bnd_null_ptr_bounds", BT_FN_PTR_CONST_PTR, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_CHKP_BUILTIN (BUILT_IN_CHKP_COPY_PTR_BOUNDS, "__bnd_copy_ptr_bounds", BT_FN_PTR_CONST_PTR_CONST_PTR, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_CHKP_BUILTIN (BUILT_IN_CHKP_NARROW_PTR_BOUNDS, "__bnd_narrow_ptr_bounds", BT_FN_PTR_CONST_PTR_CONST_PTR_SIZE, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_CHKP_BUILTIN (BUILT_IN_CHKP_STORE_PTR_BOUNDS, "__bnd_store_ptr_bounds", BT_FN_VOID_PTRPTR_CONST_PTR, ATTR_NOTHROW_LEAF_LIST)
-DEF_CHKP_BUILTIN (BUILT_IN_CHKP_CHECK_PTR_LBOUNDS, "__bnd_chk_ptr_lbounds", BT_FN_VOID_CONST_PTR, ATTR_NOTHROW_LEAF_LIST)
-DEF_CHKP_BUILTIN (BUILT_IN_CHKP_CHECK_PTR_UBOUNDS, "__bnd_chk_ptr_ubounds", BT_FN_VOID_CONST_PTR, ATTR_NOTHROW_LEAF_LIST)
-DEF_CHKP_BUILTIN (BUILT_IN_CHKP_CHECK_PTR_BOUNDS, "__bnd_chk_ptr_bounds", BT_FN_VOID_CONST_PTR_SIZE, ATTR_NOTHROW_LEAF_LIST)
-DEF_CHKP_BUILTIN (BUILT_IN_CHKP_GET_PTR_LBOUND, "__bnd_get_ptr_lbound", BT_FN_CONST_PTR_CONST_PTR, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_CHKP_BUILTIN (BUILT_IN_CHKP_GET_PTR_UBOUND, "__bnd_get_ptr_ubound", BT_FN_CONST_PTR_CONST_PTR, ATTR_CONST_NOTHROW_LEAF_LIST)
-
-/* Pointer Bounds Checker specific versions of string functions. */
-DEF_CHKP_BUILTIN (BUILT_IN_CHKP_MEMCPY_NOBND, "chkp_memcpy_nobnd", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
-DEF_CHKP_BUILTIN (BUILT_IN_CHKP_MEMCPY_NOCHK, "chkp_memcpy_nochk", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
-DEF_CHKP_BUILTIN (BUILT_IN_CHKP_MEMCPY_NOBND_NOCHK, "chkp_memcpy_nobnd_nochk", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
-DEF_CHKP_BUILTIN (BUILT_IN_CHKP_MEMMOVE_NOBND, "chkp_memmove_nobnd", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
-DEF_CHKP_BUILTIN (BUILT_IN_CHKP_MEMMOVE_NOCHK, "chkp_memmove_nochk", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
-DEF_CHKP_BUILTIN (BUILT_IN_CHKP_MEMMOVE_NOBND_NOCHK, "chkp_memmove_nobnd_nochk", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
-DEF_CHKP_BUILTIN (BUILT_IN_CHKP_MEMPCPY_NOBND, "chkp_mempcpy_nobnd", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
-DEF_CHKP_BUILTIN (BUILT_IN_CHKP_MEMPCPY_NOCHK, "chkp_mempcpy_nochk", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
-DEF_CHKP_BUILTIN (BUILT_IN_CHKP_MEMPCPY_NOBND_NOCHK, "chkp_mempcpy_nobnd_nochk", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
-DEF_CHKP_BUILTIN (BUILT_IN_CHKP_MEMSET_NOBND, "chkp_memset_nobnd", BT_FN_PTR_PTR_INT_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
-DEF_CHKP_BUILTIN (BUILT_IN_CHKP_MEMSET_NOCHK, "chkp_memset_nochk", BT_FN_PTR_PTR_INT_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
-DEF_CHKP_BUILTIN (BUILT_IN_CHKP_MEMSET_NOBND_NOCHK, "chkp_memset_nobnd_nochk", BT_FN_PTR_PTR_INT_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
#include "optabs.h"
#include "recog.h"
#include "tree-iterator.h"
-#include "gimple.h"
#include "gimplify.h"
#include "cilk.h"
tree parent = cilk_dot (fptr, CILK_TI_FRAME_PARENT, 0);
tree worker = cilk_dot (fptr, CILK_TI_FRAME_WORKER, 0);
- tree tail = cilk_dot (worker, CILK_TI_WORKER_TAIL, 1);
+ tree tail = cilk_arrow (worker, CILK_TI_WORKER_TAIL, 1);
rtx wreg = expand_expr (worker, NULL_RTX, Pmode, EXPAND_NORMAL);
if (GET_CODE (wreg) != REG)
static int export_flag; /* true if -bE */
static int aix64_flag; /* true if -b64 */
static int aixrtl_flag; /* true if -brtl */
+static int aixlazy_flag; /* true if -blazy */
#endif
enum lto_mode_d {
const char *c_file_name; /* pathname of gcc */
static char *initname, *fininame; /* names of init and fini funcs */
+
+#ifdef TARGET_AIX_VERSION
+static char *aix_shared_initname;
+static char *aix_shared_fininame; /* init/fini names as per the scheme
+ described in config/rs6000/aix.h */
+#endif
+
static struct head constructors; /* list of constructors found */
static struct head destructors; /* list of destructors found */
#ifdef COLLECT_EXPORT_LIST
SYM_DTOR = 2, /* destructor */
SYM_INIT = 3, /* shared object routine that calls all the ctors */
SYM_FINI = 4, /* shared object routine that calls all the dtors */
- SYM_DWEH = 5 /* DWARF exception handling table */
+ SYM_DWEH = 5, /* DWARF exception handling table */
+ SYM_AIXI = 6,
+ SYM_AIXD = 7
} symkind;
static symkind is_ctor_dtor (const char *);
SCAN_INIT = 1 << SYM_INIT,
SCAN_FINI = 1 << SYM_FINI,
SCAN_DWEH = 1 << SYM_DWEH,
+ SCAN_AIXI = 1 << SYM_AIXI,
+ SCAN_AIXD = 1 << SYM_AIXD,
SCAN_ALL = ~0
};
{ "GLOBAL__F_", sizeof ("GLOBAL__F_")-1, SYM_DWEH, 0 },
{ "GLOBAL__FI_", sizeof ("GLOBAL__FI_")-1, SYM_INIT, 0 },
{ "GLOBAL__FD_", sizeof ("GLOBAL__FD_")-1, SYM_FINI, 0 },
+#ifdef TARGET_AIX_VERSION
+ { "GLOBAL__AIXI_", sizeof ("GLOBAL__AIXI_")-1, SYM_AIXI, 0 },
+ { "GLOBAL__AIXD_", sizeof ("GLOBAL__AIXD_")-1, SYM_AIXD, 0 },
+#endif
{ NULL, 0, SYM_REGULAR, 0 }
};
aixrtl_flag = 1;
else if (strcmp (argv[i], "-bnortl") == 0)
aixrtl_flag = 0;
+ else if (strcmp (argv[i], "-blazy") == 0)
+ aixlazy_flag = 1;
#endif
}
vflag = debug;
if (! exports.first)
*ld2++ = concat ("-bE:", export_file, NULL);
+#ifdef TARGET_AIX_VERSION
+ add_to_list (&exports, aix_shared_initname);
+ add_to_list (&exports, aix_shared_fininame);
+#endif
+
#ifndef LD_INIT_SWITCH
add_to_list (&exports, initname);
add_to_list (&exports, fininame);
{
int pos = 0, pri;
+#ifdef TARGET_AIX_VERSION
+ /* Run dependent module initializers before any constructors in this
+ module. */
+ switch (is_ctor_dtor (name))
+ {
+ case SYM_AIXI:
+ case SYM_AIXD:
+ return INT_MIN;
+ default:
+ break;
+ }
+#endif
+
while (name[pos] == '_')
++pos;
pos += 10; /* strlen ("GLOBAL__X_") */
initname = concat ("_GLOBAL__FI_", prefix, NULL);
fininame = concat ("_GLOBAL__FD_", prefix, NULL);
+#ifdef TARGET_AIX_VERSION
+ aix_shared_initname = concat ("_GLOBAL__AIXI_", prefix, NULL);
+ aix_shared_fininame = concat ("_GLOBAL__AIXD_", prefix, NULL);
+#endif
free (prefix);
/* Write the tables as C code. */
+ /* This count variable is used to prevent multiple calls to the
+ constructors/destructors.
+ This guard against multiple calls is important on AIX as the initfini
+ functions are deliberately invoked multiple times as part of the
+ mechanisms GCC uses to order constructors across different dependent
+ shared libraries (see config/rs6000/aix.h).
+ */
fprintf (stream, "static int count;\n");
fprintf (stream, "typedef void entry_pt();\n");
write_list_with_asm (stream, "extern entry_pt ", constructors.first);
*end = '\0';
+
switch (is_ctor_dtor (name))
{
case SYM_CTOR:
switch (is_ctor_dtor (name))
{
+#if TARGET_AIX_VERSION
+ /* Add AIX shared library initalisers/finalisers
+ to the constructors/destructors list of the
+ current module. */
+ case SYM_AIXI:
+ if (! (filter & SCAN_CTOR))
+ break;
+ if (is_shared && !aixlazy_flag)
+ add_to_list (&constructors, name);
+ break;
+
+ case SYM_AIXD:
+ if (! (filter & SCAN_DTOR))
+ break;
+ if (is_shared && !aixlazy_flag)
+ add_to_list (&destructors, name);
+ break;
+#endif
+
case SYM_CTOR:
if (! (filter & SCAN_CTOR))
break;
(DF_LR_IN (ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb),
REGNO (x)))))
{
- *nonzero &= rsp->last_set_nonzero_bits;
+ unsigned HOST_WIDE_INT mask = rsp->last_set_nonzero_bits;
+
+ if (GET_MODE_PRECISION (rsp->last_set_mode) < GET_MODE_PRECISION (mode))
+ /* We don't know anything about the upper bits. */
+ mask |= GET_MODE_MASK (mode) ^ GET_MODE_MASK (rsp->last_set_mode);
+
+ *nonzero &= mask;
return NULL;
}
if (GET_MODE_PRECISION (GET_MODE (x)) < GET_MODE_PRECISION (mode))
/* We don't know anything about the upper bits. */
mask |= GET_MODE_MASK (mode) ^ GET_MODE_MASK (GET_MODE (x));
+
*nonzero &= mask;
}
Common Joined RejectNegative Enum(vect_cost_model) Var(flag_vect_cost_model) Init(VECT_COST_MODEL_DEFAULT)
Specifies the cost model for vectorization
+fsimd-cost-model=
+Common Joined RejectNegative Enum(vect_cost_model) Var(flag_simd_cost_model) Init(VECT_COST_MODEL_UNLIMITED)
+Specifies the vectorization cost model for code marked with a simd directive
+
Enum
Name(vect_cost_model) Type(enum vect_cost_model) UnknownError(unknown vectorizer cost model %qs)
static-libtsan
Driver
+static-liblsan
+Driver
+
static-libubsan
Driver
#include "langhooks.h"
#include "diagnostic-core.h"
#include "optabs.h"
+#include "pointer-set.h"
+#include "hash-table.h"
+#include "vec.h"
+#include "ggc.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-fold.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
/* qualifier_pointer | qualifier_map_mode */
qualifier_pointer_map_mode = 0x84,
/* qualifier_const_pointer | qualifier_map_mode */
- qualifier_const_pointer_map_mode = 0x86
+ qualifier_const_pointer_map_mode = 0x86,
+ /* Polynomial types. */
+ qualifier_poly = 0x100
};
typedef struct
#define TYPES_LOAD1 (aarch64_types_load1_qualifiers)
#define TYPES_LOADSTRUCT (aarch64_types_load1_qualifiers)
+static enum aarch64_type_qualifiers
+aarch64_types_bsl_p_qualifiers[SIMD_MAX_BUILTIN_ARGS]
+ = { qualifier_poly, qualifier_unsigned,
+ qualifier_poly, qualifier_poly };
+#define TYPES_BSL_P (aarch64_types_bsl_p_qualifiers)
+static enum aarch64_type_qualifiers
+aarch64_types_bsl_s_qualifiers[SIMD_MAX_BUILTIN_ARGS]
+ = { qualifier_none, qualifier_unsigned,
+ qualifier_none, qualifier_none };
+#define TYPES_BSL_S (aarch64_types_bsl_s_qualifiers)
+static enum aarch64_type_qualifiers
+aarch64_types_bsl_u_qualifiers[SIMD_MAX_BUILTIN_ARGS]
+ = { qualifier_unsigned, qualifier_unsigned,
+ qualifier_unsigned, qualifier_unsigned };
+#define TYPES_BSL_U (aarch64_types_bsl_u_qualifiers)
+
/* The first argument (return type) of a store should be void type,
which we represent with qualifier_void. Their first operand will be
a DImode pointer to the location to store to, so we must use
#define BUILTIN_VALLDI(T, N, MAP) \
VAR11 (T, N, MAP, v8qi, v16qi, v4hi, v8hi, v2si, \
v4si, v2di, v2sf, v4sf, v2df, di)
+#define BUILTIN_VALLDIF(T, N, MAP) \
+ VAR12 (T, N, MAP, v8qi, v16qi, v4hi, v8hi, v2si, \
+ v4si, v2di, v2sf, v4sf, v2df, di, df)
#define BUILTIN_VB(T, N, MAP) \
VAR2 (T, N, MAP, v8qi, v16qi)
#define BUILTIN_VD(T, N, MAP) \
VAR6 (T, N, MAP, v8qi, v16qi, v4hi, v8hi, v2si, v4si)
#define BUILTIN_VDQV(T, N, MAP) \
VAR5 (T, N, MAP, v8qi, v16qi, v4hi, v8hi, v4si)
+#define BUILTIN_VDQQH(T, N, MAP) \
+ VAR4 (T, N, MAP, v8qi, v16qi, v4hi, v8hi)
#define BUILTIN_VDQ_BHSI(T, N, MAP) \
VAR6 (T, N, MAP, v8qi, v16qi, v4hi, v8hi, v2si, v4si)
#define BUILTIN_VDQ_I(T, N, MAP) \
#undef VAR1
#define VAR1(T, N, MAP, A) \
- AARCH64_SIMD_BUILTIN_##N##A,
+ AARCH64_SIMD_BUILTIN_##T##_##N##A,
enum aarch64_builtins
{
/* Return a tree for a signed or unsigned argument of either
the mode specified by MODE, or the inner mode of MODE. */
tree
-aarch64_build_scalar_type (enum machine_mode mode, bool unsigned_p)
+aarch64_build_scalar_type (enum machine_mode mode,
+ bool unsigned_p,
+ bool poly_p)
{
#undef INT_TYPES
#define INT_TYPES \
/* Statically declare all the possible types we might need. */
#undef AARCH64_TYPE_BUILDER
#define AARCH64_TYPE_BUILDER(X) \
+ static tree X##_aarch64_type_node_p = NULL; \
static tree X##_aarch64_type_node_s = NULL; \
static tree X##_aarch64_type_node_u = NULL;
? X##_aarch64_type_node_u \
: X##_aarch64_type_node_u \
= make_unsigned_type (GET_MODE_PRECISION (mode))); \
+ else if (poly_p) \
+ return (X##_aarch64_type_node_p \
+ ? X##_aarch64_type_node_p \
+ : X##_aarch64_type_node_p \
+ = make_unsigned_type (GET_MODE_PRECISION (mode))); \
else \
return (X##_aarch64_type_node_s \
? X##_aarch64_type_node_s \
}
tree
-aarch64_build_vector_type (enum machine_mode mode, bool unsigned_p)
+aarch64_build_vector_type (enum machine_mode mode,
+ bool unsigned_p,
+ bool poly_p)
{
tree eltype;
#undef AARCH64_TYPE_BUILDER
#define AARCH64_TYPE_BUILDER(X) \
static tree X##_aarch64_type_node_s = NULL; \
- static tree X##_aarch64_type_node_u = NULL;
+ static tree X##_aarch64_type_node_u = NULL; \
+ static tree X##_aarch64_type_node_p = NULL;
VECTOR_TYPES
: X##_aarch64_type_node_u \
= build_vector_type_for_mode (aarch64_build_scalar_type \
(GET_MODE_INNER (mode), \
- unsigned_p), mode); \
+ unsigned_p, poly_p), mode); \
+ else if (poly_p) \
+ return X##_aarch64_type_node_p \
+ ? X##_aarch64_type_node_p \
+ : X##_aarch64_type_node_p \
+ = build_vector_type_for_mode (aarch64_build_scalar_type \
+ (GET_MODE_INNER (mode), \
+ unsigned_p, poly_p), mode); \
else \
return X##_aarch64_type_node_s \
? X##_aarch64_type_node_s \
: X##_aarch64_type_node_s \
= build_vector_type_for_mode (aarch64_build_scalar_type \
(GET_MODE_INNER (mode), \
- unsigned_p), mode); \
+ unsigned_p, poly_p), mode); \
break;
switch (mode)
{
default:
- eltype = aarch64_build_scalar_type (GET_MODE_INNER (mode), unsigned_p);
+ eltype = aarch64_build_scalar_type (GET_MODE_INNER (mode),
+ unsigned_p, poly_p);
return build_vector_type_for_mode (eltype, mode);
break;
VECTOR_TYPES
}
tree
-aarch64_build_type (enum machine_mode mode, bool unsigned_p)
+aarch64_build_type (enum machine_mode mode, bool unsigned_p, bool poly_p)
{
if (VECTOR_MODE_P (mode))
- return aarch64_build_vector_type (mode, unsigned_p);
+ return aarch64_build_vector_type (mode, unsigned_p, poly_p);
else
- return aarch64_build_scalar_type (mode, unsigned_p);
+ return aarch64_build_scalar_type (mode, unsigned_p, poly_p);
+}
+
+tree
+aarch64_build_signed_type (enum machine_mode mode)
+{
+ return aarch64_build_type (mode, false, false);
+}
+
+tree
+aarch64_build_unsigned_type (enum machine_mode mode)
+{
+ return aarch64_build_type (mode, true, false);
+}
+
+tree
+aarch64_build_poly_type (enum machine_mode mode)
+{
+ return aarch64_build_type (mode, false, true);
}
static void
{
unsigned int i, fcode = AARCH64_SIMD_BUILTIN_BASE + 1;
- /* In order that 'poly' types mangle correctly they must not share
- a base tree with the other scalar types, thus we must generate them
- as a special case. */
- tree aarch64_simd_polyQI_type_node =
- make_signed_type (GET_MODE_PRECISION (QImode));
- tree aarch64_simd_polyHI_type_node =
- make_signed_type (GET_MODE_PRECISION (HImode));
-
- /* Scalar type nodes. */
- tree aarch64_simd_intQI_type_node = aarch64_build_type (QImode, false);
- tree aarch64_simd_intHI_type_node = aarch64_build_type (HImode, false);
- tree aarch64_simd_intSI_type_node = aarch64_build_type (SImode, false);
- tree aarch64_simd_intDI_type_node = aarch64_build_type (DImode, false);
- tree aarch64_simd_intTI_type_node = aarch64_build_type (TImode, false);
- tree aarch64_simd_intEI_type_node = aarch64_build_type (EImode, false);
- tree aarch64_simd_intOI_type_node = aarch64_build_type (OImode, false);
- tree aarch64_simd_intCI_type_node = aarch64_build_type (CImode, false);
- tree aarch64_simd_intXI_type_node = aarch64_build_type (XImode, false);
- tree aarch64_simd_intUQI_type_node = aarch64_build_type (QImode, true);
- tree aarch64_simd_intUHI_type_node = aarch64_build_type (HImode, true);
- tree aarch64_simd_intUSI_type_node = aarch64_build_type (SImode, true);
- tree aarch64_simd_intUDI_type_node = aarch64_build_type (DImode, true);
+ /* Signed scalar type nodes. */
+ tree aarch64_simd_intQI_type_node = aarch64_build_signed_type (QImode);
+ tree aarch64_simd_intHI_type_node = aarch64_build_signed_type (HImode);
+ tree aarch64_simd_intSI_type_node = aarch64_build_signed_type (SImode);
+ tree aarch64_simd_intDI_type_node = aarch64_build_signed_type (DImode);
+ tree aarch64_simd_intTI_type_node = aarch64_build_signed_type (TImode);
+ tree aarch64_simd_intEI_type_node = aarch64_build_signed_type (EImode);
+ tree aarch64_simd_intOI_type_node = aarch64_build_signed_type (OImode);
+ tree aarch64_simd_intCI_type_node = aarch64_build_signed_type (CImode);
+ tree aarch64_simd_intXI_type_node = aarch64_build_signed_type (XImode);
+
+ /* Unsigned scalar type nodes. */
+ tree aarch64_simd_intUQI_type_node = aarch64_build_unsigned_type (QImode);
+ tree aarch64_simd_intUHI_type_node = aarch64_build_unsigned_type (HImode);
+ tree aarch64_simd_intUSI_type_node = aarch64_build_unsigned_type (SImode);
+ tree aarch64_simd_intUDI_type_node = aarch64_build_unsigned_type (DImode);
+
+ /* Poly scalar type nodes. */
+ tree aarch64_simd_polyQI_type_node = aarch64_build_poly_type (QImode);
+ tree aarch64_simd_polyHI_type_node = aarch64_build_poly_type (HImode);
/* Float type nodes. */
- tree aarch64_simd_float_type_node = aarch64_build_type (SFmode, false);
- tree aarch64_simd_double_type_node = aarch64_build_type (DFmode, false);
+ tree aarch64_simd_float_type_node = aarch64_build_signed_type (SFmode);
+ tree aarch64_simd_double_type_node = aarch64_build_signed_type (DFmode);
/* Define typedefs which exactly correspond to the modes we are basing vector
types on. If you change these names you'll need to change
type_signature[arg_num] = 'u';
print_type_signature_p = true;
}
+ else if (qualifiers & qualifier_poly)
+ {
+ type_signature[arg_num] = 'p';
+ print_type_signature_p = true;
+ }
else
type_signature[arg_num] = 's';
op_mode = GET_MODE_INNER (op_mode);
eltype = aarch64_build_type (op_mode,
- qualifiers & qualifier_unsigned);
+ qualifiers & qualifier_unsigned,
+ qualifiers & qualifier_poly);
/* Add qualifiers. */
if (qualifiers & qualifier_const)
#define AARCH64_CHECK_BUILTIN_MODE(C, N) 1
#define AARCH64_FIND_FRINT_VARIANT(N) \
(AARCH64_CHECK_BUILTIN_MODE (2, D) \
- ? aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_##N##v2df] \
+ ? aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_UNOP_##N##v2df] \
: (AARCH64_CHECK_BUILTIN_MODE (4, S) \
- ? aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_##N##v4sf] \
+ ? aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_UNOP_##N##v4sf] \
: (AARCH64_CHECK_BUILTIN_MODE (2, S) \
- ? aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_##N##v2sf] \
+ ? aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_UNOP_##N##v2sf] \
: NULL_TREE)))
if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
{
case BUILT_IN_CLZ:
{
if (AARCH64_CHECK_BUILTIN_MODE (4, S))
- return aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_clzv4si];
+ return aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_UNOP_clzv4si];
return NULL_TREE;
}
#undef AARCH64_CHECK_BUILTIN_MODE
case BUILT_IN_LFLOOR:
case BUILT_IN_IFLOORF:
{
- tree new_tree = NULL_TREE;
+ enum aarch64_builtins builtin;
if (AARCH64_CHECK_BUILTIN_MODE (2, D))
- new_tree =
- aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_lfloorv2dfv2di];
+ builtin = AARCH64_SIMD_BUILTIN_UNOP_lfloorv2dfv2di;
else if (AARCH64_CHECK_BUILTIN_MODE (4, S))
- new_tree =
- aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_lfloorv4sfv4si];
+ builtin = AARCH64_SIMD_BUILTIN_UNOP_lfloorv4sfv4si;
else if (AARCH64_CHECK_BUILTIN_MODE (2, S))
- new_tree =
- aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_lfloorv2sfv2si];
- return new_tree;
+ builtin = AARCH64_SIMD_BUILTIN_UNOP_lfloorv2sfv2si;
+ else
+ return NULL_TREE;
+
+ return aarch64_builtin_decls[builtin];
}
case BUILT_IN_LCEIL:
case BUILT_IN_ICEILF:
{
- tree new_tree = NULL_TREE;
+ enum aarch64_builtins builtin;
if (AARCH64_CHECK_BUILTIN_MODE (2, D))
- new_tree =
- aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_lceilv2dfv2di];
+ builtin = AARCH64_SIMD_BUILTIN_UNOP_lceilv2dfv2di;
else if (AARCH64_CHECK_BUILTIN_MODE (4, S))
- new_tree =
- aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_lceilv4sfv4si];
+ builtin = AARCH64_SIMD_BUILTIN_UNOP_lceilv4sfv4si;
else if (AARCH64_CHECK_BUILTIN_MODE (2, S))
- new_tree =
- aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_lceilv2sfv2si];
- return new_tree;
+ builtin = AARCH64_SIMD_BUILTIN_UNOP_lceilv2sfv2si;
+ else
+ return NULL_TREE;
+
+ return aarch64_builtin_decls[builtin];
}
case BUILT_IN_LROUND:
case BUILT_IN_IROUNDF:
{
- tree new_tree = NULL_TREE;
+ enum aarch64_builtins builtin;
if (AARCH64_CHECK_BUILTIN_MODE (2, D))
- new_tree =
- aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_lroundv2dfv2di];
+ builtin = AARCH64_SIMD_BUILTIN_UNOP_lroundv2dfv2di;
else if (AARCH64_CHECK_BUILTIN_MODE (4, S))
- new_tree =
- aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_lroundv4sfv4si];
+ builtin = AARCH64_SIMD_BUILTIN_UNOP_lroundv4sfv4si;
else if (AARCH64_CHECK_BUILTIN_MODE (2, S))
- new_tree =
- aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_lroundv2sfv2si];
- return new_tree;
+ builtin = AARCH64_SIMD_BUILTIN_UNOP_lroundv2sfv2si;
+ else
+ return NULL_TREE;
+
+ return aarch64_builtin_decls[builtin];
}
default:
#undef VAR1
#define VAR1(T, N, MAP, A) \
- case AARCH64_SIMD_BUILTIN_##N##A:
+ case AARCH64_SIMD_BUILTIN_##T##_##N##A:
tree
aarch64_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED, tree *args,
This list currently contains example CPUs that implement AArch64, and
therefore serves as a template for adding more CPUs in the future. */
-AARCH64_CORE("cortex-a53", cortexa53, 8, AARCH64_FL_FPSIMD, generic)
+AARCH64_CORE("cortex-a53", cortexa53, 8, AARCH64_FL_FPSIMD, cortexa53)
AARCH64_CORE("cortex-a57", cortexa15, 8, AARCH64_FL_FPSIMD, generic)
/* Implemented by fma<mode>4. */
BUILTIN_VDQF (TERNOP, fma, 4)
+ /* Implemented by aarch64_simd_bsl<mode>. */
+ BUILTIN_VDQQH (BSL_P, simd_bsl, 0)
+ BUILTIN_VSDQ_I_DI (BSL_U, simd_bsl, 0)
+ BUILTIN_VALLDIF (BSL_S, simd_bsl, 0)
+
(define_insn "*aarch64_simd_mov<mode>"
[(set (match_operand:VD 0 "aarch64_simd_nonimmediate_operand"
- "=w, Utv, w, ?r, ?w, ?r, w")
+ "=w, m, w, ?r, ?w, ?r, w")
(match_operand:VD 1 "aarch64_simd_general_operand"
- "Utv, w, w, w, r, r, Dn"))]
+ "m, w, w, w, r, r, Dn"))]
"TARGET_SIMD
&& (register_operand (operands[0], <MODE>mode)
|| register_operand (operands[1], <MODE>mode))"
{
switch (which_alternative)
{
- case 0: return "ld1\t{%0.<Vtype>}, %1";
- case 1: return "st1\t{%1.<Vtype>}, %0";
+ case 0: return "ldr\\t%d0, %1";
+ case 1: return "str\\t%d1, %0";
case 2: return "orr\t%0.<Vbtype>, %1.<Vbtype>, %1.<Vbtype>";
case 3: return "umov\t%0, %1.d[0]";
case 4: return "ins\t%0.d[0], %1";
(define_insn "*aarch64_simd_mov<mode>"
[(set (match_operand:VQ 0 "aarch64_simd_nonimmediate_operand"
- "=w, Utv, w, ?r, ?w, ?r, w")
+ "=w, m, w, ?r, ?w, ?r, w")
(match_operand:VQ 1 "aarch64_simd_general_operand"
- "Utv, w, w, w, r, r, Dn"))]
+ "m, w, w, w, r, r, Dn"))]
"TARGET_SIMD
&& (register_operand (operands[0], <MODE>mode)
|| register_operand (operands[1], <MODE>mode))"
switch (which_alternative)
{
case 0:
- return "ld1\t{%0.<Vtype>}, %1";
+ return "ldr\\t%q0, %1";
case 1:
- return "st1\t{%1.<Vtype>}, %0";
+ return "str\\t%q1, %0";
case 2:
return "orr\t%0.<Vbtype>, %1.<Vbtype>, %1.<Vbtype>";
case 3:
(match_operand:VQ_S 3 "register_operand" "0,0")
(match_operand:SI 2 "immediate_operand" "i,i")))]
"TARGET_SIMD"
- "@
- ins\t%0.<Vetype>[%p2], %w1
- ins\\t%0.<Vetype>[%p2], %1.<Vetype>[0]"
+ {
+ int elt = ENDIAN_LANE_N (<MODE>mode, exact_log2 (INTVAL (operands[2])));
+ operands[2] = GEN_INT ((HOST_WIDE_INT) 1 << elt);
+ switch (which_alternative)
+ {
+ case 0:
+ return "ins\\t%0.<Vetype>[%p2], %w1";
+ case 1:
+ return "ins\\t%0.<Vetype>[%p2], %1.<Vetype>[0]";
+ default:
+ gcc_unreachable ();
+ }
+ }
[(set_attr "type" "neon_from_gp<q>, neon_ins<q>")]
)
(match_operand:V2DI 3 "register_operand" "0,0")
(match_operand:SI 2 "immediate_operand" "i,i")))]
"TARGET_SIMD"
- "@
- ins\t%0.d[%p2], %1
- ins\\t%0.d[%p2], %1.d[0]"
+ {
+ int elt = ENDIAN_LANE_N (V2DImode, exact_log2 (INTVAL (operands[2])));
+ operands[2] = GEN_INT ((HOST_WIDE_INT) 1 << elt);
+ switch (which_alternative)
+ {
+ case 0:
+ return "ins\\t%0.d[%p2], %1";
+ case 1:
+ return "ins\\t%0.d[%p2], %1.d[0]";
+ default:
+ gcc_unreachable ();
+ }
+ }
[(set_attr "type" "neon_from_gp, neon_ins_q")]
)
(match_operand:VDQF 3 "register_operand" "0")
(match_operand:SI 2 "immediate_operand" "i")))]
"TARGET_SIMD"
- "ins\t%0.<Vetype>[%p2], %1.<Vetype>[0]";
+ {
+ int elt = ENDIAN_LANE_N (<MODE>mode, exact_log2 (INTVAL (operands[2])));
+
+ operands[2] = GEN_INT ((HOST_WIDE_INT)1 << elt);
+ return "ins\t%0.<Vetype>[%p2], %1.<Vetype>[0]";
+ }
[(set_attr "type" "neon_ins<q>")]
)
"TARGET_SIMD"
{
rtx tempreg = gen_reg_rtx (<VDBL>mode);
+ int lo = BYTES_BIG_ENDIAN ? 2 : 1;
+ int hi = BYTES_BIG_ENDIAN ? 1 : 2;
- emit_insn (gen_move_lo_quad_<Vdbl> (tempreg, operands[1]));
- emit_insn (gen_move_hi_quad_<Vdbl> (tempreg, operands[2]));
+ emit_insn (gen_move_lo_quad_<Vdbl> (tempreg, operands[lo]));
+ emit_insn (gen_move_hi_quad_<Vdbl> (tempreg, operands[hi]));
emit_insn (gen_aarch64_simd_vec_pack_trunc_<Vdbl> (operands[0], tempreg));
DONE;
})
(truncate:<VNARROWQ> (match_operand:VQN 1 "register_operand" "w"))
(truncate:<VNARROWQ> (match_operand:VQN 2 "register_operand" "w"))))]
"TARGET_SIMD"
- "xtn\\t%0.<Vntype>, %1.<Vtype>\;xtn2\\t%0.<V2ntype>, %2.<Vtype>"
+ {
+ if (BYTES_BIG_ENDIAN)
+ return "xtn\\t%0.<Vntype>, %2.<Vtype>\;xtn2\\t%0.<V2ntype>, %1.<Vtype>";
+ else
+ return "xtn\\t%0.<Vntype>, %1.<Vtype>\;xtn2\\t%0.<V2ntype>, %2.<Vtype>";
+ }
[(set_attr "type" "multiple")
(set_attr "length" "8")]
)
"TARGET_SIMD"
{
rtx tmp = gen_reg_rtx (V2SFmode);
- emit_insn (gen_aarch64_float_truncate_lo_v2sf (tmp, operands[1]));
+ int lo = BYTES_BIG_ENDIAN ? 2 : 1;
+ int hi = BYTES_BIG_ENDIAN ? 1 : 2;
+
+ emit_insn (gen_aarch64_float_truncate_lo_v2sf (tmp, operands[lo]));
emit_insn (gen_aarch64_float_truncate_hi_v4sf (operands[0],
- tmp, operands[2]));
+ tmp, operands[hi]));
DONE;
}
)
"TARGET_SIMD"
{
rtx tmp = gen_reg_rtx (V2SFmode);
- emit_insn (gen_move_lo_quad_v2df (tmp, operands[1]));
- emit_insn (gen_move_hi_quad_v2df (tmp, operands[2]));
+ int lo = BYTES_BIG_ENDIAN ? 2 : 1;
+ int hi = BYTES_BIG_ENDIAN ? 1 : 2;
+
+ emit_insn (gen_move_lo_quad_v2df (tmp, operands[lo]));
+ emit_insn (gen_move_hi_quad_v2df (tmp, operands[hi]));
emit_insn (gen_aarch64_float_truncate_lo_v2sf (operands[0], tmp));
DONE;
}
(unspec:VDQV [(match_operand:VDQV 1 "register_operand" "w")]
SUADDV))]
"TARGET_SIMD"
- "addv\\t%<Vetype>0, %1.<Vtype>"
+ "add<VDQV:vp>\\t%<Vetype>0, %1.<Vtype>"
[(set_attr "type" "neon_reduc_add<q>")]
)
-(define_insn "reduc_<sur>plus_v2di"
- [(set (match_operand:V2DI 0 "register_operand" "=w")
- (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "w")]
- SUADDV))]
- "TARGET_SIMD"
- "addp\\t%d0, %1.2d"
- [(set_attr "type" "neon_reduc_add_q")]
-)
-
(define_insn "reduc_<sur>plus_v2si"
[(set (match_operand:V2SI 0 "register_operand" "=w")
(unspec:V2SI [(match_operand:V2SI 1 "register_operand" "w")]
[(set_attr "type" "neon_reduc_add")]
)
-(define_insn "reduc_<sur>plus_<mode>"
+(define_insn "reduc_splus_<mode>"
[(set (match_operand:V2F 0 "register_operand" "=w")
(unspec:V2F [(match_operand:V2F 1 "register_operand" "w")]
- SUADDV))]
+ UNSPEC_FADDV))]
"TARGET_SIMD"
"faddp\\t%<Vetype>0, %1.<Vtype>"
[(set_attr "type" "neon_fp_reduc_add_<Vetype><q>")]
[(set_attr "type" "neon_fp_reduc_add_s_q")]
)
-(define_expand "reduc_<sur>plus_v4sf"
+(define_expand "reduc_splus_v4sf"
[(set (match_operand:V4SF 0 "register_operand")
(unspec:V4SF [(match_operand:V4SF 1 "register_operand")]
- SUADDV))]
+ UNSPEC_FADDV))]
"TARGET_SIMD"
{
- rtx tmp = gen_reg_rtx (V4SFmode);
- emit_insn (gen_aarch64_addpv4sf (tmp, operands[1]));
- emit_insn (gen_aarch64_addpv4sf (operands[0], tmp));
+ emit_insn (gen_aarch64_addpv4sf (operands[0], operands[1]));
+ emit_insn (gen_aarch64_addpv4sf (operands[0], operands[0]));
DONE;
})
;; 'across lanes' max and min ops.
(define_insn "reduc_<maxmin_uns>_<mode>"
- [(set (match_operand:VDQV 0 "register_operand" "=w")
- (unspec:VDQV [(match_operand:VDQV 1 "register_operand" "w")]
+ [(set (match_operand:VDQV_S 0 "register_operand" "=w")
+ (unspec:VDQV_S [(match_operand:VDQV_S 1 "register_operand" "w")]
MAXMINV))]
"TARGET_SIMD"
"<maxmin_uns_op>v\\t%<Vetype>0, %1.<Vtype>"
[(set_attr "type" "neon_reduc_minmax<q>")]
)
-(define_insn "reduc_<maxmin_uns>_v2di"
- [(set (match_operand:V2DI 0 "register_operand" "=w")
- (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "w")]
- MAXMINV))]
- "TARGET_SIMD"
- "<maxmin_uns_op>p\\t%d0, %1.2d"
- [(set_attr "type" "neon_reduc_minmax_q")]
-)
-
(define_insn "reduc_<maxmin_uns>_v2si"
[(set (match_operand:V2SI 0 "register_operand" "=w")
(unspec:V2SI [(match_operand:V2SI 1 "register_operand" "w")]
;; bif op0, op1, mask
(define_insn "aarch64_simd_bsl<mode>_internal"
- [(set (match_operand:VALL 0 "register_operand" "=w,w,w")
- (ior:VALL
- (and:VALL
+ [(set (match_operand:VALLDIF 0 "register_operand" "=w,w,w")
+ (ior:VALLDIF
+ (and:VALLDIF
(match_operand:<V_cmp_result> 1 "register_operand" " 0,w,w")
- (match_operand:VALL 2 "register_operand" " w,w,0"))
- (and:VALL
+ (match_operand:VALLDIF 2 "register_operand" " w,w,0"))
+ (and:VALLDIF
(not:<V_cmp_result>
(match_dup:<V_cmp_result> 1))
- (match_operand:VALL 3 "register_operand" " w,0,w"))
+ (match_operand:VALLDIF 3 "register_operand" " w,0,w"))
))]
"TARGET_SIMD"
"@
)
(define_expand "aarch64_simd_bsl<mode>"
- [(match_operand:VALL 0 "register_operand")
+ [(match_operand:VALLDIF 0 "register_operand")
(match_operand:<V_cmp_result> 1 "register_operand")
- (match_operand:VALL 2 "register_operand")
- (match_operand:VALL 3 "register_operand")]
+ (match_operand:VALLDIF 2 "register_operand")
+ (match_operand:VALLDIF 3 "register_operand")]
"TARGET_SIMD"
{
/* We can't alias operands together if they have different modes. */
(match_operand:VDQQH 1 "register_operand" "w")
(parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
"TARGET_SIMD"
- "smov\\t%<GPI:w>0, %1.<VDQQH:Vetype>[%2]"
+ {
+ operands[2] = GEN_INT (ENDIAN_LANE_N (<MODE>mode, INTVAL (operands[2])));
+ return "smov\\t%<GPI:w>0, %1.<VDQQH:Vetype>[%2]";
+ }
[(set_attr "type" "neon_to_gp<q>")]
)
(match_operand:VDQQH 1 "register_operand" "w")
(parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
"TARGET_SIMD"
- "umov\\t%w0, %1.<Vetype>[%2]"
+ {
+ operands[2] = GEN_INT (ENDIAN_LANE_N (<MODE>mode, INTVAL (operands[2])));
+ return "umov\\t%w0, %1.<Vetype>[%2]";
+ }
[(set_attr "type" "neon_to_gp<q>")]
)
;; Lane extraction of a value, neither sign nor zero extension
;; is guaranteed so upper bits should be considered undefined.
(define_insn "aarch64_get_lane<mode>"
- [(set (match_operand:<VEL> 0 "register_operand" "=r, w")
+ [(set (match_operand:<VEL> 0 "aarch64_simd_nonimmediate_operand" "=r, w, Utv")
(vec_select:<VEL>
- (match_operand:VALL 1 "register_operand" "w, w")
- (parallel [(match_operand:SI 2 "immediate_operand" "i, i")])))]
+ (match_operand:VALL 1 "register_operand" "w, w, w")
+ (parallel [(match_operand:SI 2 "immediate_operand" "i, i, i")])))]
"TARGET_SIMD"
- "@
- umov\\t%<vwcore>0, %1.<Vetype>[%2]
- dup\\t%<Vetype>0, %1.<Vetype>[%2]"
- [(set_attr "type" "neon_to_gp<q>, neon_dup<q>")]
+ {
+ operands[2] = GEN_INT (ENDIAN_LANE_N (<MODE>mode, INTVAL (operands[2])));
+ switch (which_alternative)
+ {
+ case 0:
+ return "umov\\t%<vwcore>0, %1.<Vetype>[%2]";
+ case 1:
+ return "dup\\t%<Vetype>0, %1.<Vetype>[%2]";
+ case 2:
+ return "st1\\t{%1.<Vetype>}[%2], %0";
+ default:
+ gcc_unreachable ();
+ }
+ }
+ [(set_attr "type" "neon_to_gp<q>, neon_dup<q>, neon_store1_one_lane<q>")]
)
(define_expand "aarch64_get_lanedi"
;; Standard pattern name vec_extract<mode>.
-(define_insn "vec_extract<mode>"
- [(set (match_operand:<VEL> 0 "aarch64_simd_nonimmediate_operand" "=r, w, Utv")
- (vec_select:<VEL>
- (match_operand:VALL 1 "register_operand" "w, w, w")
- (parallel [(match_operand:SI 2 "immediate_operand" "i,i,i")])))]
+(define_expand "vec_extract<mode>"
+ [(match_operand:<VEL> 0 "aarch64_simd_nonimmediate_operand" "")
+ (match_operand:VALL 1 "register_operand" "")
+ (match_operand:SI 2 "immediate_operand" "")]
"TARGET_SIMD"
- "@
- umov\\t%<vw>0, %1.<Vetype>[%2]
- dup\\t%<Vetype>0, %1.<Vetype>[%2]
- st1\\t{%1.<Vetype>}[%2], %0"
- [(set_attr "type" "neon_to_gp<q>, neon_dup<q>, neon_store1_one_lane<q>")]
-)
-
+{
+ emit_insn
+ (gen_aarch64_get_lane<mode> (operands[0], operands[1], operands[2]));
+ DONE;
+})
#include "recog.h"
#include "langhooks.h"
#include "diagnostic-core.h"
+#include "pointer-set.h"
+#include "hash-table.h"
+#include "vec.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-fold.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimplify.h"
#include "optabs.h"
NAMED_PARAM (memmov_cost, 4)
};
+static const struct tune_params cortexa53_tunings =
+{
+ &cortexa53_extra_costs,
+ &generic_addrcost_table,
+ &generic_regmove_cost,
+ &generic_vector_cost,
+ NAMED_PARAM (memmov_cost, 4)
+};
+
/* A processor implementing AArch64. */
struct processor
{
if (flag_omit_frame_pointer && !faked_omit_frame_pointer)
return false;
else if (flag_omit_leaf_frame_pointer)
- return !crtl->is_leaf;
+ return !crtl->is_leaf || df_regs_ever_live_p (LR_REGNUM);
return true;
}
of faked_omit_frame_pointer here (which is true when we always
wish to keep non-leaf frame pointers but only wish to keep leaf frame
pointers when LR is clobbered). */
- if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM
+ if (to == STACK_POINTER_REGNUM
&& df_regs_ever_live_p (LR_REGNUM)
&& faked_omit_frame_pointer)
return false;
((MODE) == V4SImode || (MODE) == V8HImode || (MODE) == V16QImode \
|| (MODE) == V4SFmode || (MODE) == V2DImode || mode == V2DFmode)
+#define ENDIAN_LANE_N(mode, n) \
+ (BYTES_BIG_ENDIAN ? GET_MODE_NUNITS (mode) - 1 - n : n)
+
#endif /* GCC_AARCH64_H */
return result;
}
-__extension__ static __inline float32x2_t __attribute__ ((__always_inline__))
-vbsl_f32 (uint32x2_t a, float32x2_t b, float32x2_t c)
-{
- float32x2_t result;
- __asm__ ("bsl %0.8b, %2.8b, %3.8b"
- : "=w"(result)
- : "0"(a), "w"(b), "w"(c)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline poly8x8_t __attribute__ ((__always_inline__))
-vbsl_p8 (uint8x8_t a, poly8x8_t b, poly8x8_t c)
-{
- poly8x8_t result;
- __asm__ ("bsl %0.8b, %2.8b, %3.8b"
- : "=w"(result)
- : "0"(a), "w"(b), "w"(c)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline poly16x4_t __attribute__ ((__always_inline__))
-vbsl_p16 (uint16x4_t a, poly16x4_t b, poly16x4_t c)
-{
- poly16x4_t result;
- __asm__ ("bsl %0.8b, %2.8b, %3.8b"
- : "=w"(result)
- : "0"(a), "w"(b), "w"(c)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline int8x8_t __attribute__ ((__always_inline__))
-vbsl_s8 (uint8x8_t a, int8x8_t b, int8x8_t c)
-{
- int8x8_t result;
- __asm__ ("bsl %0.8b, %2.8b, %3.8b"
- : "=w"(result)
- : "0"(a), "w"(b), "w"(c)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline int16x4_t __attribute__ ((__always_inline__))
-vbsl_s16 (uint16x4_t a, int16x4_t b, int16x4_t c)
-{
- int16x4_t result;
- __asm__ ("bsl %0.8b, %2.8b, %3.8b"
- : "=w"(result)
- : "0"(a), "w"(b), "w"(c)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline int32x2_t __attribute__ ((__always_inline__))
-vbsl_s32 (uint32x2_t a, int32x2_t b, int32x2_t c)
-{
- int32x2_t result;
- __asm__ ("bsl %0.8b, %2.8b, %3.8b"
- : "=w"(result)
- : "0"(a), "w"(b), "w"(c)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline int64x1_t __attribute__ ((__always_inline__))
-vbsl_s64 (uint64x1_t a, int64x1_t b, int64x1_t c)
-{
- int64x1_t result;
- __asm__ ("bsl %0.8b, %2.8b, %3.8b"
- : "=w"(result)
- : "0"(a), "w"(b), "w"(c)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__))
-vbsl_u8 (uint8x8_t a, uint8x8_t b, uint8x8_t c)
-{
- uint8x8_t result;
- __asm__ ("bsl %0.8b, %2.8b, %3.8b"
- : "=w"(result)
- : "0"(a), "w"(b), "w"(c)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__))
-vbsl_u16 (uint16x4_t a, uint16x4_t b, uint16x4_t c)
-{
- uint16x4_t result;
- __asm__ ("bsl %0.8b, %2.8b, %3.8b"
- : "=w"(result)
- : "0"(a), "w"(b), "w"(c)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__))
-vbsl_u32 (uint32x2_t a, uint32x2_t b, uint32x2_t c)
-{
- uint32x2_t result;
- __asm__ ("bsl %0.8b, %2.8b, %3.8b"
- : "=w"(result)
- : "0"(a), "w"(b), "w"(c)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__))
-vbsl_u64 (uint64x1_t a, uint64x1_t b, uint64x1_t c)
-{
- uint64x1_t result;
- __asm__ ("bsl %0.8b, %2.8b, %3.8b"
- : "=w"(result)
- : "0"(a), "w"(b), "w"(c)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline float32x4_t __attribute__ ((__always_inline__))
-vbslq_f32 (uint32x4_t a, float32x4_t b, float32x4_t c)
-{
- float32x4_t result;
- __asm__ ("bsl %0.16b, %2.16b, %3.16b"
- : "=w"(result)
- : "0"(a), "w"(b), "w"(c)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline float64x2_t __attribute__ ((__always_inline__))
-vbslq_f64 (uint64x2_t a, float64x2_t b, float64x2_t c)
-{
- float64x2_t result;
- __asm__ ("bsl %0.16b, %2.16b, %3.16b"
- : "=w"(result)
- : "0"(a), "w"(b), "w"(c)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline poly8x16_t __attribute__ ((__always_inline__))
-vbslq_p8 (uint8x16_t a, poly8x16_t b, poly8x16_t c)
-{
- poly8x16_t result;
- __asm__ ("bsl %0.16b, %2.16b, %3.16b"
- : "=w"(result)
- : "0"(a), "w"(b), "w"(c)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline poly16x8_t __attribute__ ((__always_inline__))
-vbslq_p16 (uint16x8_t a, poly16x8_t b, poly16x8_t c)
-{
- poly16x8_t result;
- __asm__ ("bsl %0.16b, %2.16b, %3.16b"
- : "=w"(result)
- : "0"(a), "w"(b), "w"(c)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline int8x16_t __attribute__ ((__always_inline__))
-vbslq_s8 (uint8x16_t a, int8x16_t b, int8x16_t c)
-{
- int8x16_t result;
- __asm__ ("bsl %0.16b, %2.16b, %3.16b"
- : "=w"(result)
- : "0"(a), "w"(b), "w"(c)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline int16x8_t __attribute__ ((__always_inline__))
-vbslq_s16 (uint16x8_t a, int16x8_t b, int16x8_t c)
-{
- int16x8_t result;
- __asm__ ("bsl %0.16b, %2.16b, %3.16b"
- : "=w"(result)
- : "0"(a), "w"(b), "w"(c)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline int32x4_t __attribute__ ((__always_inline__))
-vbslq_s32 (uint32x4_t a, int32x4_t b, int32x4_t c)
-{
- int32x4_t result;
- __asm__ ("bsl %0.16b, %2.16b, %3.16b"
- : "=w"(result)
- : "0"(a), "w"(b), "w"(c)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline int64x2_t __attribute__ ((__always_inline__))
-vbslq_s64 (uint64x2_t a, int64x2_t b, int64x2_t c)
-{
- int64x2_t result;
- __asm__ ("bsl %0.16b, %2.16b, %3.16b"
- : "=w"(result)
- : "0"(a), "w"(b), "w"(c)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__))
-vbslq_u8 (uint8x16_t a, uint8x16_t b, uint8x16_t c)
-{
- uint8x16_t result;
- __asm__ ("bsl %0.16b, %2.16b, %3.16b"
- : "=w"(result)
- : "0"(a), "w"(b), "w"(c)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline uint16x8_t __attribute__ ((__always_inline__))
-vbslq_u16 (uint16x8_t a, uint16x8_t b, uint16x8_t c)
-{
- uint16x8_t result;
- __asm__ ("bsl %0.16b, %2.16b, %3.16b"
- : "=w"(result)
- : "0"(a), "w"(b), "w"(c)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__))
-vbslq_u32 (uint32x4_t a, uint32x4_t b, uint32x4_t c)
-{
- uint32x4_t result;
- __asm__ ("bsl %0.16b, %2.16b, %3.16b"
- : "=w"(result)
- : "0"(a), "w"(b), "w"(c)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__))
-vbslq_u64 (uint64x2_t a, uint64x2_t b, uint64x2_t c)
-{
- uint64x2_t result;
- __asm__ ("bsl %0.16b, %2.16b, %3.16b"
- : "=w"(result)
- : "0"(a), "w"(b), "w"(c)
- : /* No clobbers */);
- return result;
-}
-
__extension__ static __inline int8x8_t __attribute__ ((__always_inline__))
vcls_s8 (int8x8_t a)
{
return result;
}
-__extension__ static __inline float32x2_t __attribute__ ((__always_inline__))
-vmov_n_f32 (float32_t a)
-{
- float32x2_t result;
- __asm__ ("dup %0.2s, %w1"
- : "=w"(result)
- : "r"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline poly8x8_t __attribute__ ((__always_inline__))
-vmov_n_p8 (uint32_t a)
-{
- poly8x8_t result;
- __asm__ ("dup %0.8b,%w1"
- : "=w"(result)
- : "r"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline poly16x4_t __attribute__ ((__always_inline__))
-vmov_n_p16 (uint32_t a)
-{
- poly16x4_t result;
- __asm__ ("dup %0.4h,%w1"
- : "=w"(result)
- : "r"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline int8x8_t __attribute__ ((__always_inline__))
-vmov_n_s8 (int32_t a)
-{
- int8x8_t result;
- __asm__ ("dup %0.8b,%w1"
- : "=w"(result)
- : "r"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline int16x4_t __attribute__ ((__always_inline__))
-vmov_n_s16 (int32_t a)
-{
- int16x4_t result;
- __asm__ ("dup %0.4h,%w1"
- : "=w"(result)
- : "r"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline int32x2_t __attribute__ ((__always_inline__))
-vmov_n_s32 (int32_t a)
-{
- int32x2_t result;
- __asm__ ("dup %0.2s,%w1"
- : "=w"(result)
- : "r"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline int64x1_t __attribute__ ((__always_inline__))
-vmov_n_s64 (int64_t a)
-{
- int64x1_t result;
- __asm__ ("ins %0.d[0],%x1"
- : "=w"(result)
- : "r"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__))
-vmov_n_u8 (uint32_t a)
-{
- uint8x8_t result;
- __asm__ ("dup %0.8b,%w1"
- : "=w"(result)
- : "r"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__))
-vmov_n_u16 (uint32_t a)
-{
- uint16x4_t result;
- __asm__ ("dup %0.4h,%w1"
- : "=w"(result)
- : "r"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__))
-vmov_n_u32 (uint32_t a)
-{
- uint32x2_t result;
- __asm__ ("dup %0.2s,%w1"
- : "=w"(result)
- : "r"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__))
-vmov_n_u64 (uint64_t a)
-{
- uint64x1_t result;
- __asm__ ("ins %0.d[0],%x1"
- : "=w"(result)
- : "r"(a)
- : /* No clobbers */);
- return result;
-}
-
__extension__ static __inline int16x8_t __attribute__ ((__always_inline__))
vmovl_high_s8 (int8x16_t a)
{
return result;
}
-__extension__ static __inline float32x4_t __attribute__ ((__always_inline__))
-vmovq_n_f32 (float32_t a)
-{
- float32x4_t result;
- __asm__ ("dup %0.4s, %w1"
- : "=w"(result)
- : "r"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline float64x2_t __attribute__ ((__always_inline__))
-vmovq_n_f64 (float64_t a)
-{
- return (float64x2_t) {a, a};
-}
-
-__extension__ static __inline poly8x16_t __attribute__ ((__always_inline__))
-vmovq_n_p8 (uint32_t a)
-{
- poly8x16_t result;
- __asm__ ("dup %0.16b,%w1"
- : "=w"(result)
- : "r"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline poly16x8_t __attribute__ ((__always_inline__))
-vmovq_n_p16 (uint32_t a)
-{
- poly16x8_t result;
- __asm__ ("dup %0.8h,%w1"
- : "=w"(result)
- : "r"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline int8x16_t __attribute__ ((__always_inline__))
-vmovq_n_s8 (int32_t a)
-{
- int8x16_t result;
- __asm__ ("dup %0.16b,%w1"
- : "=w"(result)
- : "r"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline int16x8_t __attribute__ ((__always_inline__))
-vmovq_n_s16 (int32_t a)
-{
- int16x8_t result;
- __asm__ ("dup %0.8h,%w1"
- : "=w"(result)
- : "r"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline int32x4_t __attribute__ ((__always_inline__))
-vmovq_n_s32 (int32_t a)
-{
- int32x4_t result;
- __asm__ ("dup %0.4s,%w1"
- : "=w"(result)
- : "r"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline int64x2_t __attribute__ ((__always_inline__))
-vmovq_n_s64 (int64_t a)
-{
- int64x2_t result;
- __asm__ ("dup %0.2d,%x1"
- : "=w"(result)
- : "r"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__))
-vmovq_n_u8 (uint32_t a)
-{
- uint8x16_t result;
- __asm__ ("dup %0.16b,%w1"
- : "=w"(result)
- : "r"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline uint16x8_t __attribute__ ((__always_inline__))
-vmovq_n_u16 (uint32_t a)
-{
- uint16x8_t result;
- __asm__ ("dup %0.8h,%w1"
- : "=w"(result)
- : "r"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__))
-vmovq_n_u32 (uint32_t a)
-{
- uint32x4_t result;
- __asm__ ("dup %0.4s,%w1"
- : "=w"(result)
- : "r"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__))
-vmovq_n_u64 (uint64_t a)
-{
- uint64x2_t result;
- __asm__ ("dup %0.2d,%x1"
- : "=w"(result)
- : "r"(a)
- : /* No clobbers */);
- return result;
-}
-
__extension__ static __inline float32x2_t __attribute__ ((__always_inline__))
vmul_n_f32 (float32x2_t a, float32_t b)
{
return result;
}
-__extension__ static __inline int8x8_t __attribute__ ((__always_inline__))
-vtbx1_s8 (int8x8_t r, int8x8_t tab, int8x8_t idx)
-{
- int8x8_t result;
- int8x8_t tmp1;
- int8x16_t temp = vcombine_s8 (tab, vcreate_s8 (__AARCH64_UINT64_C (0x0)));
- __asm__ ("movi %0.8b, 8\n\t"
- "cmhs %0.8b, %3.8b, %0.8b\n\t"
- "tbl %1.8b, {%2.16b}, %3.8b\n\t"
- "bsl %0.8b, %4.8b, %1.8b\n\t"
- : "+w"(result), "=&w"(tmp1)
- : "w"(temp), "w"(idx), "w"(r)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__))
-vtbx1_u8 (uint8x8_t r, uint8x8_t tab, uint8x8_t idx)
-{
- uint8x8_t result;
- uint8x8_t tmp1;
- uint8x16_t temp = vcombine_u8 (tab, vcreate_u8 (__AARCH64_UINT64_C (0x0)));
- __asm__ ("movi %0.8b, 8\n\t"
- "cmhs %0.8b, %3.8b, %0.8b\n\t"
- "tbl %1.8b, {%2.16b}, %3.8b\n\t"
- "bsl %0.8b, %4.8b, %1.8b\n\t"
- : "+w"(result), "=&w"(tmp1)
- : "w"(temp), "w"(idx), "w"(r)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline poly8x8_t __attribute__ ((__always_inline__))
-vtbx1_p8 (poly8x8_t r, poly8x8_t tab, uint8x8_t idx)
-{
- poly8x8_t result;
- poly8x8_t tmp1;
- poly8x16_t temp = vcombine_p8 (tab, vcreate_p8 (__AARCH64_UINT64_C (0x0)));
- __asm__ ("movi %0.8b, 8\n\t"
- "cmhs %0.8b, %3.8b, %0.8b\n\t"
- "tbl %1.8b, {%2.16b}, %3.8b\n\t"
- "bsl %0.8b, %4.8b, %1.8b\n\t"
- : "+w"(result), "=&w"(tmp1)
- : "w"(temp), "w"(idx), "w"(r)
- : /* No clobbers */);
- return result;
-}
-
__extension__ static __inline int8x8_t __attribute__ ((__always_inline__))
vtbx2_s8 (int8x8_t r, int8x8x2_t tab, int8x8_t idx)
{
int8x8_t result = r;
- int8x16_t temp = vcombine_s8 (tab.val[0], tab.val[1]);
- __asm__ ("tbx %0.8b, {%1.16b}, %2.8b"
- : "+w"(result)
- : "w"(temp), "w"(idx)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__))
-vtbx2_u8 (uint8x8_t r, uint8x8x2_t tab, uint8x8_t idx)
-{
- uint8x8_t result = r;
- uint8x16_t temp = vcombine_u8 (tab.val[0], tab.val[1]);
- __asm__ ("tbx %0.8b, {%1.16b}, %2.8b"
- : "+w"(result)
- : "w"(temp), "w"(idx)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline poly8x8_t __attribute__ ((__always_inline__))
-vtbx2_p8 (poly8x8_t r, poly8x8x2_t tab, uint8x8_t idx)
-{
- poly8x8_t result = r;
- poly8x16_t temp = vcombine_p8 (tab.val[0], tab.val[1]);
- __asm__ ("tbx %0.8b, {%1.16b}, %2.8b"
- : "+w"(result)
- : "w"(temp), "w"(idx)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline int8x8_t __attribute__ ((__always_inline__))
-vtbx3_s8 (int8x8_t r, int8x8x3_t tab, int8x8_t idx)
-{
- int8x8_t result;
- int8x8_t tmp1;
- int8x16x2_t temp;
- temp.val[0] = vcombine_s8 (tab.val[0], tab.val[1]);
- temp.val[1] = vcombine_s8 (tab.val[2], vcreate_s8 (__AARCH64_UINT64_C (0x0)));
- __asm__ ("ld1 {v16.16b - v17.16b}, %2\n\t"
- "movi %0.8b, 24\n\t"
- "cmhs %0.8b, %3.8b, %0.8b\n\t"
- "tbl %1.8b, {v16.16b - v17.16b}, %3.8b\n\t"
- "bsl %0.8b, %4.8b, %1.8b\n\t"
- : "+w"(result), "=&w"(tmp1)
- : "Q"(temp), "w"(idx), "w"(r)
- : "v16", "v17", "memory");
+ int8x16_t temp = vcombine_s8 (tab.val[0], tab.val[1]);
+ __asm__ ("tbx %0.8b, {%1.16b}, %2.8b"
+ : "+w"(result)
+ : "w"(temp), "w"(idx)
+ : /* No clobbers */);
return result;
}
__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__))
-vtbx3_u8 (uint8x8_t r, uint8x8x3_t tab, uint8x8_t idx)
+vtbx2_u8 (uint8x8_t r, uint8x8x2_t tab, uint8x8_t idx)
{
- uint8x8_t result;
- uint8x8_t tmp1;
- uint8x16x2_t temp;
- temp.val[0] = vcombine_u8 (tab.val[0], tab.val[1]);
- temp.val[1] = vcombine_u8 (tab.val[2], vcreate_u8 (__AARCH64_UINT64_C (0x0)));
- __asm__ ("ld1 {v16.16b - v17.16b}, %2\n\t"
- "movi %0.8b, 24\n\t"
- "cmhs %0.8b, %3.8b, %0.8b\n\t"
- "tbl %1.8b, {v16.16b - v17.16b}, %3.8b\n\t"
- "bsl %0.8b, %4.8b, %1.8b\n\t"
- : "+w"(result), "=&w"(tmp1)
- : "Q"(temp), "w"(idx), "w"(r)
- : "v16", "v17", "memory");
+ uint8x8_t result = r;
+ uint8x16_t temp = vcombine_u8 (tab.val[0], tab.val[1]);
+ __asm__ ("tbx %0.8b, {%1.16b}, %2.8b"
+ : "+w"(result)
+ : "w"(temp), "w"(idx)
+ : /* No clobbers */);
return result;
}
__extension__ static __inline poly8x8_t __attribute__ ((__always_inline__))
-vtbx3_p8 (poly8x8_t r, poly8x8x3_t tab, uint8x8_t idx)
+vtbx2_p8 (poly8x8_t r, poly8x8x2_t tab, uint8x8_t idx)
{
- poly8x8_t result;
- poly8x8_t tmp1;
- poly8x16x2_t temp;
- temp.val[0] = vcombine_p8 (tab.val[0], tab.val[1]);
- temp.val[1] = vcombine_p8 (tab.val[2], vcreate_p8 (__AARCH64_UINT64_C (0x0)));
- __asm__ ("ld1 {v16.16b - v17.16b}, %2\n\t"
- "movi %0.8b, 24\n\t"
- "cmhs %0.8b, %3.8b, %0.8b\n\t"
- "tbl %1.8b, {v16.16b - v17.16b}, %3.8b\n\t"
- "bsl %0.8b, %4.8b, %1.8b\n\t"
- : "+w"(result), "=&w"(tmp1)
- : "Q"(temp), "w"(idx), "w"(r)
- : "v16", "v17", "memory");
+ poly8x8_t result = r;
+ poly8x16_t temp = vcombine_p8 (tab.val[0], tab.val[1]);
+ __asm__ ("tbx %0.8b, {%1.16b}, %2.8b"
+ : "+w"(result)
+ : "w"(temp), "w"(idx)
+ : /* No clobbers */);
return result;
}
return __a + __b;
}
+#if __AARCH64EB__
+#define __LANE0(__t) ((__t) - 1)
+#else
+#define __LANE0(__t) 0
+#endif
+
/* vaddv */
__extension__ static __inline int8_t __attribute__ ((__always_inline__))
vaddv_s8 (int8x8_t __a)
{
- return vget_lane_s8 (__builtin_aarch64_reduc_splus_v8qi (__a), 0);
+ return vget_lane_s8 (__builtin_aarch64_reduc_splus_v8qi (__a), __LANE0 (8));
}
__extension__ static __inline int16_t __attribute__ ((__always_inline__))
vaddv_s16 (int16x4_t __a)
{
- return vget_lane_s16 (__builtin_aarch64_reduc_splus_v4hi (__a), 0);
+ return vget_lane_s16 (__builtin_aarch64_reduc_splus_v4hi (__a), __LANE0 (4));
}
__extension__ static __inline int32_t __attribute__ ((__always_inline__))
vaddv_s32 (int32x2_t __a)
{
- return vget_lane_s32 (__builtin_aarch64_reduc_splus_v2si (__a), 0);
+ return vget_lane_s32 (__builtin_aarch64_reduc_splus_v2si (__a), __LANE0 (2));
}
__extension__ static __inline uint8_t __attribute__ ((__always_inline__))
vaddv_u8 (uint8x8_t __a)
{
return vget_lane_u8 ((uint8x8_t)
- __builtin_aarch64_reduc_uplus_v8qi ((int8x8_t) __a), 0);
+ __builtin_aarch64_reduc_uplus_v8qi ((int8x8_t) __a),
+ __LANE0 (8));
}
__extension__ static __inline uint16_t __attribute__ ((__always_inline__))
vaddv_u16 (uint16x4_t __a)
{
return vget_lane_u16 ((uint16x4_t)
- __builtin_aarch64_reduc_uplus_v4hi ((int16x4_t) __a), 0);
+ __builtin_aarch64_reduc_uplus_v4hi ((int16x4_t) __a),
+ __LANE0 (4));
}
__extension__ static __inline uint32_t __attribute__ ((__always_inline__))
vaddv_u32 (uint32x2_t __a)
{
return vget_lane_u32 ((uint32x2_t)
- __builtin_aarch64_reduc_uplus_v2si ((int32x2_t) __a), 0);
+ __builtin_aarch64_reduc_uplus_v2si ((int32x2_t) __a),
+ __LANE0 (2));
}
__extension__ static __inline int8_t __attribute__ ((__always_inline__))
vaddvq_s8 (int8x16_t __a)
{
- return vgetq_lane_s8 (__builtin_aarch64_reduc_splus_v16qi (__a), 0);
+ return vgetq_lane_s8 (__builtin_aarch64_reduc_splus_v16qi (__a),
+ __LANE0 (16));
}
__extension__ static __inline int16_t __attribute__ ((__always_inline__))
vaddvq_s16 (int16x8_t __a)
{
- return vgetq_lane_s16 (__builtin_aarch64_reduc_splus_v8hi (__a), 0);
+ return vgetq_lane_s16 (__builtin_aarch64_reduc_splus_v8hi (__a), __LANE0 (8));
}
__extension__ static __inline int32_t __attribute__ ((__always_inline__))
vaddvq_s32 (int32x4_t __a)
{
- return vgetq_lane_s32 (__builtin_aarch64_reduc_splus_v4si (__a), 0);
+ return vgetq_lane_s32 (__builtin_aarch64_reduc_splus_v4si (__a), __LANE0 (4));
}
__extension__ static __inline int64_t __attribute__ ((__always_inline__))
vaddvq_s64 (int64x2_t __a)
{
- return vgetq_lane_s64 (__builtin_aarch64_reduc_splus_v2di (__a), 0);
+ return vgetq_lane_s64 (__builtin_aarch64_reduc_splus_v2di (__a), __LANE0 (2));
}
__extension__ static __inline uint8_t __attribute__ ((__always_inline__))
vaddvq_u8 (uint8x16_t __a)
{
return vgetq_lane_u8 ((uint8x16_t)
- __builtin_aarch64_reduc_uplus_v16qi ((int8x16_t) __a), 0);
+ __builtin_aarch64_reduc_uplus_v16qi ((int8x16_t) __a),
+ __LANE0 (16));
}
__extension__ static __inline uint16_t __attribute__ ((__always_inline__))
vaddvq_u16 (uint16x8_t __a)
{
return vgetq_lane_u16 ((uint16x8_t)
- __builtin_aarch64_reduc_uplus_v8hi ((int16x8_t) __a), 0);
+ __builtin_aarch64_reduc_uplus_v8hi ((int16x8_t) __a),
+ __LANE0 (8));
}
__extension__ static __inline uint32_t __attribute__ ((__always_inline__))
vaddvq_u32 (uint32x4_t __a)
{
return vgetq_lane_u32 ((uint32x4_t)
- __builtin_aarch64_reduc_uplus_v4si ((int32x4_t) __a), 0);
+ __builtin_aarch64_reduc_uplus_v4si ((int32x4_t) __a),
+ __LANE0 (4));
}
__extension__ static __inline uint64_t __attribute__ ((__always_inline__))
vaddvq_u64 (uint64x2_t __a)
{
return vgetq_lane_u64 ((uint64x2_t)
- __builtin_aarch64_reduc_uplus_v2di ((int64x2_t) __a), 0);
+ __builtin_aarch64_reduc_uplus_v2di ((int64x2_t) __a),
+ __LANE0 (2));
}
__extension__ static __inline float32_t __attribute__ ((__always_inline__))
vaddv_f32 (float32x2_t __a)
{
- float32x2_t t = __builtin_aarch64_reduc_splus_v2sf (__a);
- return vget_lane_f32 (t, 0);
+ float32x2_t __t = __builtin_aarch64_reduc_splus_v2sf (__a);
+ return vget_lane_f32 (__t, __LANE0 (2));
}
__extension__ static __inline float32_t __attribute__ ((__always_inline__))
vaddvq_f32 (float32x4_t __a)
{
- float32x4_t t = __builtin_aarch64_reduc_splus_v4sf (__a);
- return vgetq_lane_f32 (t, 0);
+ float32x4_t __t = __builtin_aarch64_reduc_splus_v4sf (__a);
+ return vgetq_lane_f32 (__t, __LANE0 (4));
}
__extension__ static __inline float64_t __attribute__ ((__always_inline__))
vaddvq_f64 (float64x2_t __a)
{
- float64x2_t t = __builtin_aarch64_reduc_splus_v2df (__a);
- return vgetq_lane_f64 (t, 0);
+ float64x2_t __t = __builtin_aarch64_reduc_splus_v2df (__a);
+ return vgetq_lane_f64 (__t, __LANE0 (2));
+}
+
+/* vbsl */
+
+__extension__ static __inline float32x2_t __attribute__ ((__always_inline__))
+vbsl_f32 (uint32x2_t __a, float32x2_t __b, float32x2_t __c)
+{
+ return __builtin_aarch64_simd_bslv2sf_suss (__a, __b, __c);
+}
+
+__extension__ static __inline poly8x8_t __attribute__ ((__always_inline__))
+vbsl_p8 (uint8x8_t __a, poly8x8_t __b, poly8x8_t __c)
+{
+ return __builtin_aarch64_simd_bslv8qi_pupp (__a, __b, __c);
+}
+
+__extension__ static __inline poly16x4_t __attribute__ ((__always_inline__))
+vbsl_p16 (uint16x4_t __a, poly16x4_t __b, poly16x4_t __c)
+{
+ return __builtin_aarch64_simd_bslv4hi_pupp (__a, __b, __c);
+}
+
+__extension__ static __inline int8x8_t __attribute__ ((__always_inline__))
+vbsl_s8 (uint8x8_t __a, int8x8_t __b, int8x8_t __c)
+{
+ return __builtin_aarch64_simd_bslv8qi_suss (__a, __b, __c);
+}
+
+__extension__ static __inline int16x4_t __attribute__ ((__always_inline__))
+vbsl_s16 (uint16x4_t __a, int16x4_t __b, int16x4_t __c)
+{
+ return __builtin_aarch64_simd_bslv4hi_suss (__a, __b, __c);
+}
+
+__extension__ static __inline int32x2_t __attribute__ ((__always_inline__))
+vbsl_s32 (uint32x2_t __a, int32x2_t __b, int32x2_t __c)
+{
+ return __builtin_aarch64_simd_bslv2si_suss (__a, __b, __c);
+}
+
+__extension__ static __inline int64x1_t __attribute__ ((__always_inline__))
+vbsl_s64 (uint64x1_t __a, int64x1_t __b, int64x1_t __c)
+{
+ return __builtin_aarch64_simd_bsldi_suss (__a, __b, __c);
+}
+
+__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__))
+vbsl_u8 (uint8x8_t __a, uint8x8_t __b, uint8x8_t __c)
+{
+ return __builtin_aarch64_simd_bslv8qi_uuuu (__a, __b, __c);
+}
+
+__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__))
+vbsl_u16 (uint16x4_t __a, uint16x4_t __b, uint16x4_t __c)
+{
+ return __builtin_aarch64_simd_bslv4hi_uuuu (__a, __b, __c);
+}
+
+__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__))
+vbsl_u32 (uint32x2_t __a, uint32x2_t __b, uint32x2_t __c)
+{
+ return __builtin_aarch64_simd_bslv2si_uuuu (__a, __b, __c);
+}
+
+__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__))
+vbsl_u64 (uint64x1_t __a, uint64x1_t __b, uint64x1_t __c)
+{
+ return __builtin_aarch64_simd_bsldi_uuuu (__a, __b, __c);
+}
+
+__extension__ static __inline float32x4_t __attribute__ ((__always_inline__))
+vbslq_f32 (uint32x4_t __a, float32x4_t __b, float32x4_t __c)
+{
+ return __builtin_aarch64_simd_bslv4sf_suss (__a, __b, __c);
+}
+
+__extension__ static __inline float64x2_t __attribute__ ((__always_inline__))
+vbslq_f64 (uint64x2_t __a, float64x2_t __b, float64x2_t __c)
+{
+ return __builtin_aarch64_simd_bslv2df_suss (__a, __b, __c);
+}
+
+__extension__ static __inline poly8x16_t __attribute__ ((__always_inline__))
+vbslq_p8 (uint8x16_t __a, poly8x16_t __b, poly8x16_t __c)
+{
+ return __builtin_aarch64_simd_bslv16qi_pupp (__a, __b, __c);
+}
+
+__extension__ static __inline poly16x8_t __attribute__ ((__always_inline__))
+vbslq_p16 (uint16x8_t __a, poly16x8_t __b, poly16x8_t __c)
+{
+ return __builtin_aarch64_simd_bslv8hi_pupp (__a, __b, __c);
+}
+
+__extension__ static __inline int8x16_t __attribute__ ((__always_inline__))
+vbslq_s8 (uint8x16_t __a, int8x16_t __b, int8x16_t __c)
+{
+ return __builtin_aarch64_simd_bslv16qi_suss (__a, __b, __c);
+}
+
+__extension__ static __inline int16x8_t __attribute__ ((__always_inline__))
+vbslq_s16 (uint16x8_t __a, int16x8_t __b, int16x8_t __c)
+{
+ return __builtin_aarch64_simd_bslv8hi_suss (__a, __b, __c);
+}
+
+__extension__ static __inline int32x4_t __attribute__ ((__always_inline__))
+vbslq_s32 (uint32x4_t __a, int32x4_t __b, int32x4_t __c)
+{
+ return __builtin_aarch64_simd_bslv4si_suss (__a, __b, __c);
+}
+
+__extension__ static __inline int64x2_t __attribute__ ((__always_inline__))
+vbslq_s64 (uint64x2_t __a, int64x2_t __b, int64x2_t __c)
+{
+ return __builtin_aarch64_simd_bslv2di_suss (__a, __b, __c);
+}
+
+__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__))
+vbslq_u8 (uint8x16_t __a, uint8x16_t __b, uint8x16_t __c)
+{
+ return __builtin_aarch64_simd_bslv16qi_uuuu (__a, __b, __c);
+}
+
+__extension__ static __inline uint16x8_t __attribute__ ((__always_inline__))
+vbslq_u16 (uint16x8_t __a, uint16x8_t __b, uint16x8_t __c)
+{
+ return __builtin_aarch64_simd_bslv8hi_uuuu (__a, __b, __c);
+}
+
+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__))
+vbslq_u32 (uint32x4_t __a, uint32x4_t __b, uint32x4_t __c)
+{
+ return __builtin_aarch64_simd_bslv4si_uuuu (__a, __b, __c);
+}
+
+__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__))
+vbslq_u64 (uint64x2_t __a, uint64x2_t __b, uint64x2_t __c)
+{
+ return __builtin_aarch64_simd_bslv2di_uuuu (__a, __b, __c);
}
/* vcage */
__extension__ static __inline float32_t __attribute__ ((__always_inline__))
vmaxv_f32 (float32x2_t __a)
{
- return vget_lane_f32 (__builtin_aarch64_reduc_smax_nan_v2sf (__a), 0);
+ return vget_lane_f32 (__builtin_aarch64_reduc_smax_nan_v2sf (__a),
+ __LANE0 (2));
}
__extension__ static __inline int8_t __attribute__ ((__always_inline__))
vmaxv_s8 (int8x8_t __a)
{
- return vget_lane_s8 (__builtin_aarch64_reduc_smax_v8qi (__a), 0);
+ return vget_lane_s8 (__builtin_aarch64_reduc_smax_v8qi (__a), __LANE0 (8));
}
__extension__ static __inline int16_t __attribute__ ((__always_inline__))
vmaxv_s16 (int16x4_t __a)
{
- return vget_lane_s16 (__builtin_aarch64_reduc_smax_v4hi (__a), 0);
+ return vget_lane_s16 (__builtin_aarch64_reduc_smax_v4hi (__a), __LANE0 (4));
}
__extension__ static __inline int32_t __attribute__ ((__always_inline__))
vmaxv_s32 (int32x2_t __a)
{
- return vget_lane_s32 (__builtin_aarch64_reduc_smax_v2si (__a), 0);
+ return vget_lane_s32 (__builtin_aarch64_reduc_smax_v2si (__a), __LANE0 (2));
}
__extension__ static __inline uint8_t __attribute__ ((__always_inline__))
vmaxv_u8 (uint8x8_t __a)
{
return vget_lane_u8 ((uint8x8_t)
- __builtin_aarch64_reduc_umax_v8qi ((int8x8_t) __a), 0);
+ __builtin_aarch64_reduc_umax_v8qi ((int8x8_t) __a),
+ __LANE0 (8));
}
__extension__ static __inline uint16_t __attribute__ ((__always_inline__))
vmaxv_u16 (uint16x4_t __a)
{
return vget_lane_u16 ((uint16x4_t)
- __builtin_aarch64_reduc_umax_v4hi ((int16x4_t) __a), 0);
+ __builtin_aarch64_reduc_umax_v4hi ((int16x4_t) __a),
+ __LANE0 (4));
}
__extension__ static __inline uint32_t __attribute__ ((__always_inline__))
vmaxv_u32 (uint32x2_t __a)
{
return vget_lane_u32 ((uint32x2_t)
- __builtin_aarch64_reduc_umax_v2si ((int32x2_t) __a), 0);
+ __builtin_aarch64_reduc_umax_v2si ((int32x2_t) __a),
+ __LANE0 (2));
}
__extension__ static __inline float32_t __attribute__ ((__always_inline__))
vmaxvq_f32 (float32x4_t __a)
{
- return vgetq_lane_f32 (__builtin_aarch64_reduc_smax_nan_v4sf (__a), 0);
+ return vgetq_lane_f32 (__builtin_aarch64_reduc_smax_nan_v4sf (__a),
+ __LANE0 (4));
}
__extension__ static __inline float64_t __attribute__ ((__always_inline__))
vmaxvq_f64 (float64x2_t __a)
{
- return vgetq_lane_f64 (__builtin_aarch64_reduc_smax_nan_v2df (__a), 0);
+ return vgetq_lane_f64 (__builtin_aarch64_reduc_smax_nan_v2df (__a),
+ __LANE0 (2));
}
__extension__ static __inline int8_t __attribute__ ((__always_inline__))
vmaxvq_s8 (int8x16_t __a)
{
- return vgetq_lane_s8 (__builtin_aarch64_reduc_smax_v16qi (__a), 0);
+ return vgetq_lane_s8 (__builtin_aarch64_reduc_smax_v16qi (__a), __LANE0 (16));
}
__extension__ static __inline int16_t __attribute__ ((__always_inline__))
vmaxvq_s16 (int16x8_t __a)
{
- return vgetq_lane_s16 (__builtin_aarch64_reduc_smax_v8hi (__a), 0);
+ return vgetq_lane_s16 (__builtin_aarch64_reduc_smax_v8hi (__a), __LANE0 (8));
}
__extension__ static __inline int32_t __attribute__ ((__always_inline__))
vmaxvq_s32 (int32x4_t __a)
{
- return vgetq_lane_s32 (__builtin_aarch64_reduc_smax_v4si (__a), 0);
+ return vgetq_lane_s32 (__builtin_aarch64_reduc_smax_v4si (__a), __LANE0 (4));
}
__extension__ static __inline uint8_t __attribute__ ((__always_inline__))
vmaxvq_u8 (uint8x16_t __a)
{
return vgetq_lane_u8 ((uint8x16_t)
- __builtin_aarch64_reduc_umax_v16qi ((int8x16_t) __a), 0);
+ __builtin_aarch64_reduc_umax_v16qi ((int8x16_t) __a),
+ __LANE0 (16));
}
__extension__ static __inline uint16_t __attribute__ ((__always_inline__))
vmaxvq_u16 (uint16x8_t __a)
{
return vgetq_lane_u16 ((uint16x8_t)
- __builtin_aarch64_reduc_umax_v8hi ((int16x8_t) __a), 0);
+ __builtin_aarch64_reduc_umax_v8hi ((int16x8_t) __a),
+ __LANE0 (8));
}
__extension__ static __inline uint32_t __attribute__ ((__always_inline__))
vmaxvq_u32 (uint32x4_t __a)
{
return vgetq_lane_u32 ((uint32x4_t)
- __builtin_aarch64_reduc_umax_v4si ((int32x4_t) __a), 0);
+ __builtin_aarch64_reduc_umax_v4si ((int32x4_t) __a),
+ __LANE0 (4));
}
/* vmaxnmv */
__extension__ static __inline float32_t __attribute__ ((__always_inline__))
vmaxnmv_f32 (float32x2_t __a)
{
- return vget_lane_f32 (__builtin_aarch64_reduc_smax_v2sf (__a), 0);
+ return vget_lane_f32 (__builtin_aarch64_reduc_smax_v2sf (__a),
+ __LANE0 (2));
}
__extension__ static __inline float32_t __attribute__ ((__always_inline__))
vmaxnmvq_f32 (float32x4_t __a)
{
- return vgetq_lane_f32 (__builtin_aarch64_reduc_smax_v4sf (__a), 0);
+ return vgetq_lane_f32 (__builtin_aarch64_reduc_smax_v4sf (__a), __LANE0 (4));
}
__extension__ static __inline float64_t __attribute__ ((__always_inline__))
vmaxnmvq_f64 (float64x2_t __a)
{
- return vgetq_lane_f64 (__builtin_aarch64_reduc_smax_v2df (__a), 0);
+ return vgetq_lane_f64 (__builtin_aarch64_reduc_smax_v2df (__a), __LANE0 (2));
}
/* vmin */
__extension__ static __inline float32_t __attribute__ ((__always_inline__))
vminv_f32 (float32x2_t __a)
{
- return vget_lane_f32 (__builtin_aarch64_reduc_smin_nan_v2sf (__a), 0);
+ return vget_lane_f32 (__builtin_aarch64_reduc_smin_nan_v2sf (__a),
+ __LANE0 (2));
}
__extension__ static __inline int8_t __attribute__ ((__always_inline__))
vminv_s8 (int8x8_t __a)
{
- return vget_lane_s8 (__builtin_aarch64_reduc_smin_v8qi (__a), 0);
+ return vget_lane_s8 (__builtin_aarch64_reduc_smin_v8qi (__a),
+ __LANE0 (8));
}
__extension__ static __inline int16_t __attribute__ ((__always_inline__))
vminv_s16 (int16x4_t __a)
{
- return vget_lane_s16 (__builtin_aarch64_reduc_smin_v4hi (__a), 0);
+ return vget_lane_s16 (__builtin_aarch64_reduc_smin_v4hi (__a), __LANE0 (4));
}
__extension__ static __inline int32_t __attribute__ ((__always_inline__))
vminv_s32 (int32x2_t __a)
{
- return vget_lane_s32 (__builtin_aarch64_reduc_smin_v2si (__a), 0);
+ return vget_lane_s32 (__builtin_aarch64_reduc_smin_v2si (__a), __LANE0 (2));
}
__extension__ static __inline uint8_t __attribute__ ((__always_inline__))
vminv_u8 (uint8x8_t __a)
{
return vget_lane_u8 ((uint8x8_t)
- __builtin_aarch64_reduc_umin_v8qi ((int8x8_t) __a), 0);
+ __builtin_aarch64_reduc_umin_v8qi ((int8x8_t) __a),
+ __LANE0 (8));
}
__extension__ static __inline uint16_t __attribute__ ((__always_inline__))
vminv_u16 (uint16x4_t __a)
{
return vget_lane_u16 ((uint16x4_t)
- __builtin_aarch64_reduc_umin_v4hi ((int16x4_t) __a), 0);
+ __builtin_aarch64_reduc_umin_v4hi ((int16x4_t) __a),
+ __LANE0 (4));
}
__extension__ static __inline uint32_t __attribute__ ((__always_inline__))
vminv_u32 (uint32x2_t __a)
{
return vget_lane_u32 ((uint32x2_t)
- __builtin_aarch64_reduc_umin_v2si ((int32x2_t) __a), 0);
+ __builtin_aarch64_reduc_umin_v2si ((int32x2_t) __a),
+ __LANE0 (2));
}
__extension__ static __inline float32_t __attribute__ ((__always_inline__))
vminvq_f32 (float32x4_t __a)
{
- return vgetq_lane_f32 (__builtin_aarch64_reduc_smin_nan_v4sf (__a), 0);
+ return vgetq_lane_f32 (__builtin_aarch64_reduc_smin_nan_v4sf (__a),
+ __LANE0 (4));
}
__extension__ static __inline float64_t __attribute__ ((__always_inline__))
vminvq_f64 (float64x2_t __a)
{
- return vgetq_lane_f64 (__builtin_aarch64_reduc_smin_nan_v2df (__a), 0);
+ return vgetq_lane_f64 (__builtin_aarch64_reduc_smin_nan_v2df (__a),
+ __LANE0 (2));
}
__extension__ static __inline int8_t __attribute__ ((__always_inline__))
vminvq_s8 (int8x16_t __a)
{
- return vgetq_lane_s8 (__builtin_aarch64_reduc_smin_v16qi (__a), 0);
+ return vgetq_lane_s8 (__builtin_aarch64_reduc_smin_v16qi (__a), __LANE0 (16));
}
__extension__ static __inline int16_t __attribute__ ((__always_inline__))
vminvq_s16 (int16x8_t __a)
{
- return vgetq_lane_s16 (__builtin_aarch64_reduc_smin_v8hi (__a), 0);
+ return vgetq_lane_s16 (__builtin_aarch64_reduc_smin_v8hi (__a), __LANE0 (8));
}
__extension__ static __inline int32_t __attribute__ ((__always_inline__))
vminvq_s32 (int32x4_t __a)
{
- return vgetq_lane_s32 (__builtin_aarch64_reduc_smin_v4si (__a), 0);
+ return vgetq_lane_s32 (__builtin_aarch64_reduc_smin_v4si (__a), __LANE0 (4));
}
__extension__ static __inline uint8_t __attribute__ ((__always_inline__))
vminvq_u8 (uint8x16_t __a)
{
return vgetq_lane_u8 ((uint8x16_t)
- __builtin_aarch64_reduc_umin_v16qi ((int8x16_t) __a), 0);
+ __builtin_aarch64_reduc_umin_v16qi ((int8x16_t) __a),
+ __LANE0 (16));
}
__extension__ static __inline uint16_t __attribute__ ((__always_inline__))
vminvq_u16 (uint16x8_t __a)
{
return vgetq_lane_u16 ((uint16x8_t)
- __builtin_aarch64_reduc_umin_v8hi ((int16x8_t) __a), 0);
+ __builtin_aarch64_reduc_umin_v8hi ((int16x8_t) __a),
+ __LANE0 (8));
}
__extension__ static __inline uint32_t __attribute__ ((__always_inline__))
vminvq_u32 (uint32x4_t __a)
{
return vgetq_lane_u32 ((uint32x4_t)
- __builtin_aarch64_reduc_umin_v4si ((int32x4_t) __a), 0);
+ __builtin_aarch64_reduc_umin_v4si ((int32x4_t) __a),
+ __LANE0 (4));
}
/* vminnmv */
__extension__ static __inline float32_t __attribute__ ((__always_inline__))
vminnmv_f32 (float32x2_t __a)
{
- return vget_lane_f32 (__builtin_aarch64_reduc_smin_v2sf (__a), 0);
+ return vget_lane_f32 (__builtin_aarch64_reduc_smin_v2sf (__a), __LANE0 (2));
}
__extension__ static __inline float32_t __attribute__ ((__always_inline__))
vminnmvq_f32 (float32x4_t __a)
{
- return vgetq_lane_f32 (__builtin_aarch64_reduc_smin_v4sf (__a), 0);
+ return vgetq_lane_f32 (__builtin_aarch64_reduc_smin_v4sf (__a), __LANE0 (4));
}
__extension__ static __inline float64_t __attribute__ ((__always_inline__))
vminnmvq_f64 (float64x2_t __a)
{
- return vgetq_lane_f64 (__builtin_aarch64_reduc_smin_v2df (__a), 0);
+ return vgetq_lane_f64 (__builtin_aarch64_reduc_smin_v2df (__a), __LANE0 (2));
}
/* vmla */
return (__a - (__b * __aarch64_vgetq_lane_u32 (__c, __lane)));
}
+/* vmov_n_ */
+
+__extension__ static __inline float32x2_t __attribute__ ((__always_inline__))
+vmov_n_f32 (float32_t __a)
+{
+ return vdup_n_f32 (__a);
+}
+
+__extension__ static __inline float64x1_t __attribute__ ((__always_inline__))
+vmov_n_f64 (float64_t __a)
+{
+ return __a;
+}
+
+__extension__ static __inline poly8x8_t __attribute__ ((__always_inline__))
+vmov_n_p8 (poly8_t __a)
+{
+ return vdup_n_p8 (__a);
+}
+
+__extension__ static __inline poly16x4_t __attribute__ ((__always_inline__))
+vmov_n_p16 (poly16_t __a)
+{
+ return vdup_n_p16 (__a);
+}
+
+__extension__ static __inline int8x8_t __attribute__ ((__always_inline__))
+vmov_n_s8 (int8_t __a)
+{
+ return vdup_n_s8 (__a);
+}
+
+__extension__ static __inline int16x4_t __attribute__ ((__always_inline__))
+vmov_n_s16 (int16_t __a)
+{
+ return vdup_n_s16 (__a);
+}
+
+__extension__ static __inline int32x2_t __attribute__ ((__always_inline__))
+vmov_n_s32 (int32_t __a)
+{
+ return vdup_n_s32 (__a);
+}
+
+__extension__ static __inline int64x1_t __attribute__ ((__always_inline__))
+vmov_n_s64 (int64_t __a)
+{
+ return __a;
+}
+
+__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__))
+vmov_n_u8 (uint8_t __a)
+{
+ return vdup_n_u8 (__a);
+}
+
+__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__))
+vmov_n_u16 (uint16_t __a)
+{
+ return vdup_n_u16 (__a);
+}
+
+__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__))
+vmov_n_u32 (uint32_t __a)
+{
+ return vdup_n_u32 (__a);
+}
+
+__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__))
+vmov_n_u64 (uint64_t __a)
+{
+ return __a;
+}
+
+__extension__ static __inline float32x4_t __attribute__ ((__always_inline__))
+vmovq_n_f32 (float32_t __a)
+{
+ return vdupq_n_f32 (__a);
+}
+
+__extension__ static __inline float64x2_t __attribute__ ((__always_inline__))
+vmovq_n_f64 (float64_t __a)
+{
+ return vdupq_n_f64 (__a);
+}
+
+__extension__ static __inline poly8x16_t __attribute__ ((__always_inline__))
+vmovq_n_p8 (poly8_t __a)
+{
+ return vdupq_n_p8 (__a);
+}
+
+__extension__ static __inline poly16x8_t __attribute__ ((__always_inline__))
+vmovq_n_p16 (poly16_t __a)
+{
+ return vdupq_n_p16 (__a);
+}
+
+__extension__ static __inline int8x16_t __attribute__ ((__always_inline__))
+vmovq_n_s8 (int8_t __a)
+{
+ return vdupq_n_s8 (__a);
+}
+
+__extension__ static __inline int16x8_t __attribute__ ((__always_inline__))
+vmovq_n_s16 (int16_t __a)
+{
+ return vdupq_n_s16 (__a);
+}
+
+__extension__ static __inline int32x4_t __attribute__ ((__always_inline__))
+vmovq_n_s32 (int32_t __a)
+{
+ return vdupq_n_s32 (__a);
+}
+
+__extension__ static __inline int64x2_t __attribute__ ((__always_inline__))
+vmovq_n_s64 (int64_t __a)
+{
+ return vdupq_n_s64 (__a);
+}
+
+__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__))
+vmovq_n_u8 (uint8_t __a)
+{
+ return vdupq_n_u8 (__a);
+}
+
+__extension__ static __inline uint16x8_t __attribute__ ((__always_inline__))
+vmovq_n_u16 (uint16_t __a)
+{
+ return vdupq_n_u16 (__a);
+}
+
+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__))
+vmovq_n_u32 (uint32_t __a)
+{
+ return vdupq_n_u32 (__a);
+}
+
+__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__))
+vmovq_n_u64 (uint64_t __a)
+{
+ return vdupq_n_u64 (__a);
+}
+
/* vmul_lane */
__extension__ static __inline float32x2_t __attribute__ ((__always_inline__))
return __a - __b;
}
+/* vtbx1 */
+
+__extension__ static __inline int8x8_t __attribute__ ((__always_inline__))
+vtbx1_s8 (int8x8_t __r, int8x8_t __tab, int8x8_t __idx)
+{
+ uint8x8_t __mask = vclt_u8 (vreinterpret_u8_s8 (__idx),
+ vmov_n_u8 (8));
+ int8x8_t __tbl = vtbl1_s8 (__tab, __idx);
+
+ return vbsl_s8 (__mask, __tbl, __r);
+}
+
+__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__))
+vtbx1_u8 (uint8x8_t __r, uint8x8_t __tab, uint8x8_t __idx)
+{
+ uint8x8_t __mask = vclt_u8 (__idx, vmov_n_u8 (8));
+ uint8x8_t __tbl = vtbl1_u8 (__tab, __idx);
+
+ return vbsl_u8 (__mask, __tbl, __r);
+}
+
+__extension__ static __inline poly8x8_t __attribute__ ((__always_inline__))
+vtbx1_p8 (poly8x8_t __r, poly8x8_t __tab, uint8x8_t __idx)
+{
+ uint8x8_t __mask = vclt_u8 (__idx, vmov_n_u8 (8));
+ poly8x8_t __tbl = vtbl1_p8 (__tab, __idx);
+
+ return vbsl_p8 (__mask, __tbl, __r);
+}
+
+/* vtbx3 */
+
+__extension__ static __inline int8x8_t __attribute__ ((__always_inline__))
+vtbx3_s8 (int8x8_t __r, int8x8x3_t __tab, int8x8_t __idx)
+{
+ uint8x8_t __mask = vclt_u8 (vreinterpret_u8_s8 (__idx),
+ vmov_n_u8 (24));
+ int8x8_t __tbl = vtbl3_s8 (__tab, __idx);
+
+ return vbsl_s8 (__mask, __tbl, __r);
+}
+
+__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__))
+vtbx3_u8 (uint8x8_t __r, uint8x8x3_t __tab, uint8x8_t __idx)
+{
+ uint8x8_t __mask = vclt_u8 (__idx, vmov_n_u8 (24));
+ uint8x8_t __tbl = vtbl3_u8 (__tab, __idx);
+
+ return vbsl_u8 (__mask, __tbl, __r);
+}
+
+__extension__ static __inline poly8x8_t __attribute__ ((__always_inline__))
+vtbx3_p8 (poly8x8_t __r, poly8x8x3_t __tab, uint8x8_t __idx)
+{
+ uint8x8_t __mask = vclt_u8 (__idx, vmov_n_u8 (24));
+ poly8x8_t __tbl = vtbl3_p8 (__tab, __idx);
+
+ return vbsl_p8 (__mask, __tbl, __r);
+}
+
/* vtrn */
__extension__ static __inline float32x2x2_t __attribute__ ((__always_inline__))
/* End of optimal implementations in approved order. */
+#undef __LANE0
+
#undef __aarch64_vget_lane_any
#undef __aarch64_vget_lane_f32
#undef __aarch64_vget_lane_f64
;; All vector modes and DI.
(define_mode_iterator VALLDI [V8QI V16QI V4HI V8HI V2SI V4SI V2DI V2SF V4SF V2DF DI])
+;; All vector modes and DI and DF.
+(define_mode_iterator VALLDIF [V8QI V16QI V4HI V8HI V2SI V4SI
+ V2DI V2SF V4SF V2DF DI DF])
+
;; Vector modes for Integer reduction across lanes.
-(define_mode_iterator VDQV [V8QI V16QI V4HI V8HI V4SI])
+(define_mode_iterator VDQV [V8QI V16QI V4HI V8HI V4SI V2DI])
+
+;; Vector modes(except V2DI) for Integer reduction across lanes.
+(define_mode_iterator VDQV_S [V8QI V16QI V4HI V8HI V4SI])
;; All double integer narrow-able modes.
(define_mode_iterator VDN [V4HI V2SI DI])
(V4HI "8b") (V8HI "16b")
(V2SI "8b") (V4SI "16b")
(V2DI "16b") (V2SF "8b")
- (V4SF "16b") (V2DF "16b")])
+ (V4SF "16b") (V2DF "16b")
+ (DI "8b") (DF "8b")])
;; Define element mode for each vector mode.
(define_mode_attr VEL [(V8QI "QI") (V16QI "QI")
(V2DF "_q")
(QI "") (HI "") (SI "") (DI "") (SF "") (DF "")])
+(define_mode_attr vp [(V8QI "v") (V16QI "v")
+ (V4HI "v") (V8HI "v")
+ (V2SI "p") (V4SI "v")
+ (V2DI "p") (V2DF "p")
+ (V2SF "p") (V4SF "v")])
+
;; -------------------------------------------------------------------
;; Code Iterators
;; -------------------------------------------------------------------
#include "debug.h"
#include "langhooks.h"
#include "splay-tree.h"
+#include "pointer-set.h"
+#include "hash-table.h"
+#include "vec.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-fold.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimplify.h"
#include "gimple-ssa.h"
extern rtx arm_gen_return_addr_mask (void);
extern void arm_reload_in_hi (rtx *);
extern void arm_reload_out_hi (rtx *);
+extern int arm_max_const_double_inline_cost (void);
extern int arm_const_double_inline_cost (rtx);
extern bool arm_const_double_by_parts (rtx);
extern bool arm_const_double_by_immediates (rtx);
than core registers. */
int prefer_neon_for_64bits = 0;
+/* Nonzero if we shouldn't use literal pools. */
+bool arm_disable_literal_pool = false;
+
/* In case of a PRE_INC, POST_INC, PRE_DEC, POST_DEC memory reference,
we must report the mode of the memory reference from
TARGET_PRINT_OPERAND to TARGET_PRINT_OPERAND_ADDRESS. */
{
/* ALU */
{
- COSTS_N_INSNS (1), /* Arith. */
- COSTS_N_INSNS (1), /* Logical. */
- COSTS_N_INSNS (1), /* Shift. */
- COSTS_N_INSNS (1), /* Shift_reg. */
+ 0, /* Arith. */
+ 0, /* Logical. */
+ 0, /* Shift. */
+ 0, /* Shift_reg. */
COSTS_N_INSNS (1), /* Arith_shift. */
COSTS_N_INSNS (1), /* Arith_shift_reg. */
COSTS_N_INSNS (1), /* Log_shift. */
COSTS_N_INSNS (1), /* Log_shift_reg. */
- COSTS_N_INSNS (1), /* Extend. */
- COSTS_N_INSNS (2), /* Extend_arith. */
- COSTS_N_INSNS (2), /* Bfi. */
- COSTS_N_INSNS (1), /* Bfx. */
- COSTS_N_INSNS (1), /* Clz. */
- COSTS_N_INSNS (1), /* non_exec. */
+ 0, /* Extend. */
+ COSTS_N_INSNS (1), /* Extend_arith. */
+ COSTS_N_INSNS (1), /* Bfi. */
+ 0, /* Bfx. */
+ 0, /* Clz. */
+ 0, /* non_exec. */
true /* non_exec_costs_exec. */
},
/* MULT SImode */
{
{
- COSTS_N_INSNS (3), /* Simple. */
- COSTS_N_INSNS (4), /* Flag_setting. */
- COSTS_N_INSNS (3), /* Extend. */
- COSTS_N_INSNS (4), /* Add. */
- COSTS_N_INSNS (4), /* Extend_add. */
- COSTS_N_INSNS (19) /* Idiv. */
+ COSTS_N_INSNS (2), /* Simple. */
+ COSTS_N_INSNS (3), /* Flag_setting. */
+ COSTS_N_INSNS (2), /* Extend. */
+ COSTS_N_INSNS (2), /* Add. */
+ COSTS_N_INSNS (2), /* Extend_add. */
+ COSTS_N_INSNS (18) /* Idiv. */
},
/* MULT DImode */
{
0, /* Simple (N/A). */
0, /* Flag_setting (N/A). */
- COSTS_N_INSNS (4), /* Extend. */
+ COSTS_N_INSNS (3), /* Extend. */
0, /* Add (N/A). */
- COSTS_N_INSNS (6), /* Extend_add. */
+ COSTS_N_INSNS (3), /* Extend_add. */
0 /* Idiv (N/A). */
}
},
/* LD/ST */
{
- COSTS_N_INSNS (4), /* Load. */
- COSTS_N_INSNS (4), /* Load_sign_extend. */
- COSTS_N_INSNS (4), /* Ldrd. */
- COSTS_N_INSNS (5), /* Ldm_1st. */
+ COSTS_N_INSNS (3), /* Load. */
+ COSTS_N_INSNS (3), /* Load_sign_extend. */
+ COSTS_N_INSNS (3), /* Ldrd. */
+ COSTS_N_INSNS (4), /* Ldm_1st. */
1, /* Ldm_regs_per_insn_1st. */
2, /* Ldm_regs_per_insn_subsequent. */
- COSTS_N_INSNS (5), /* Loadf. */
- COSTS_N_INSNS (5), /* Loadd. */
+ COSTS_N_INSNS (4), /* Loadf. */
+ COSTS_N_INSNS (4), /* Loadd. */
+ 0, /* Load_unaligned. */
+ 0, /* Store. */
+ 0, /* Strd. */
+ COSTS_N_INSNS (1), /* Stm_1st. */
+ 1, /* Stm_regs_per_insn_1st. */
+ 2, /* Stm_regs_per_insn_subsequent. */
+ 0, /* Storef. */
+ 0, /* Stored. */
+ 0 /* Store_unaligned. */
+ },
+ {
+ /* FP SFmode */
+ {
+ COSTS_N_INSNS (17), /* Div. */
+ COSTS_N_INSNS (4), /* Mult. */
+ COSTS_N_INSNS (8), /* Mult_addsub. */
+ COSTS_N_INSNS (8), /* Fma. */
+ COSTS_N_INSNS (4), /* Addsub. */
+ COSTS_N_INSNS (2), /* Fpconst. */
+ COSTS_N_INSNS (2), /* Neg. */
+ COSTS_N_INSNS (5), /* Compare. */
+ COSTS_N_INSNS (4), /* Widen. */
+ COSTS_N_INSNS (4), /* Narrow. */
+ COSTS_N_INSNS (4), /* Toint. */
+ COSTS_N_INSNS (4), /* Fromint. */
+ COSTS_N_INSNS (4) /* Roundint. */
+ },
+ /* FP DFmode */
+ {
+ COSTS_N_INSNS (31), /* Div. */
+ COSTS_N_INSNS (4), /* Mult. */
+ COSTS_N_INSNS (8), /* Mult_addsub. */
+ COSTS_N_INSNS (8), /* Fma. */
+ COSTS_N_INSNS (4), /* Addsub. */
+ COSTS_N_INSNS (2), /* Fpconst. */
+ COSTS_N_INSNS (2), /* Neg. */
+ COSTS_N_INSNS (2), /* Compare. */
+ COSTS_N_INSNS (4), /* Widen. */
+ COSTS_N_INSNS (4), /* Narrow. */
+ COSTS_N_INSNS (4), /* Toint. */
+ COSTS_N_INSNS (4), /* Fromint. */
+ COSTS_N_INSNS (4) /* Roundint. */
+ }
+ },
+ /* Vector */
+ {
+ COSTS_N_INSNS (1) /* Alu. */
+ }
+};
+
+const struct cpu_cost_table v7m_extra_costs =
+{
+ /* ALU */
+ {
+ 0, /* Arith. */
+ 0, /* Logical. */
+ 0, /* Shift. */
+ 0, /* Shift_reg. */
+ 0, /* Arith_shift. */
+ COSTS_N_INSNS (1), /* Arith_shift_reg. */
+ 0, /* Log_shift. */
+ COSTS_N_INSNS (1), /* Log_shift_reg. */
+ 0, /* Extend. */
+ COSTS_N_INSNS (1), /* Extend_arith. */
+ 0, /* Bfi. */
+ 0, /* Bfx. */
+ 0, /* Clz. */
+ COSTS_N_INSNS (1), /* non_exec. */
+ false /* non_exec_costs_exec. */
+ },
+ {
+ /* MULT SImode */
+ {
+ COSTS_N_INSNS (1), /* Simple. */
+ COSTS_N_INSNS (1), /* Flag_setting. */
+ COSTS_N_INSNS (2), /* Extend. */
+ COSTS_N_INSNS (1), /* Add. */
+ COSTS_N_INSNS (3), /* Extend_add. */
+ COSTS_N_INSNS (8) /* Idiv. */
+ },
+ /* MULT DImode */
+ {
+ 0, /* Simple (N/A). */
+ 0, /* Flag_setting (N/A). */
+ COSTS_N_INSNS (2), /* Extend. */
+ 0, /* Add (N/A). */
+ COSTS_N_INSNS (3), /* Extend_add. */
+ 0 /* Idiv (N/A). */
+ }
+ },
+ /* LD/ST */
+ {
+ COSTS_N_INSNS (2), /* Load. */
+ 0, /* Load_sign_extend. */
+ COSTS_N_INSNS (3), /* Ldrd. */
+ COSTS_N_INSNS (2), /* Ldm_1st. */
+ 1, /* Ldm_regs_per_insn_1st. */
+ 1, /* Ldm_regs_per_insn_subsequent. */
+ COSTS_N_INSNS (2), /* Loadf. */
+ COSTS_N_INSNS (3), /* Loadd. */
COSTS_N_INSNS (1), /* Load_unaligned. */
- COSTS_N_INSNS (1), /* Store. */
- COSTS_N_INSNS (1), /* Strd. */
+ COSTS_N_INSNS (2), /* Store. */
+ COSTS_N_INSNS (3), /* Strd. */
COSTS_N_INSNS (2), /* Stm_1st. */
1, /* Stm_regs_per_insn_1st. */
- 2, /* Stm_regs_per_insn_subsequent. */
- COSTS_N_INSNS (1), /* Storef. */
- COSTS_N_INSNS (1), /* Stored. */
- COSTS_N_INSNS (1) /* Store_unaligned. */
+ 1, /* Stm_regs_per_insn_subsequent. */
+ COSTS_N_INSNS (2), /* Storef. */
+ COSTS_N_INSNS (3), /* Stored. */
+ COSTS_N_INSNS (1) /* Store_unaligned. */
},
{
/* FP SFmode */
{
- COSTS_N_INSNS (18), /* Div. */
- COSTS_N_INSNS (5), /* Mult. */
- COSTS_N_INSNS (3), /* Mult_addsub. */
- COSTS_N_INSNS (13), /* Fma. */
- COSTS_N_INSNS (5), /* Addsub. */
- COSTS_N_INSNS (5), /* Fpconst. */
- COSTS_N_INSNS (3), /* Neg. */
- COSTS_N_INSNS (3), /* Compare. */
- COSTS_N_INSNS (3), /* Widen. */
- COSTS_N_INSNS (3), /* Narrow. */
- COSTS_N_INSNS (3), /* Toint. */
- COSTS_N_INSNS (3), /* Fromint. */
- COSTS_N_INSNS (3) /* Roundint. */
+ COSTS_N_INSNS (7), /* Div. */
+ COSTS_N_INSNS (2), /* Mult. */
+ COSTS_N_INSNS (5), /* Mult_addsub. */
+ COSTS_N_INSNS (3), /* Fma. */
+ COSTS_N_INSNS (1), /* Addsub. */
+ 0, /* Fpconst. */
+ 0, /* Neg. */
+ 0, /* Compare. */
+ 0, /* Widen. */
+ 0, /* Narrow. */
+ 0, /* Toint. */
+ 0, /* Fromint. */
+ 0 /* Roundint. */
},
/* FP DFmode */
{
- COSTS_N_INSNS (32), /* Div. */
+ COSTS_N_INSNS (15), /* Div. */
COSTS_N_INSNS (5), /* Mult. */
- COSTS_N_INSNS (3), /* Mult_addsub. */
- COSTS_N_INSNS (13), /* Fma. */
- COSTS_N_INSNS (5), /* Addsub. */
- COSTS_N_INSNS (3), /* Fpconst. */
- COSTS_N_INSNS (3), /* Neg. */
- COSTS_N_INSNS (3), /* Compare. */
- COSTS_N_INSNS (3), /* Widen. */
- COSTS_N_INSNS (3), /* Narrow. */
- COSTS_N_INSNS (3), /* Toint. */
- COSTS_N_INSNS (3), /* Fromint. */
- COSTS_N_INSNS (3) /* Roundint. */
+ COSTS_N_INSNS (7), /* Mult_addsub. */
+ COSTS_N_INSNS (7), /* Fma. */
+ COSTS_N_INSNS (3), /* Addsub. */
+ 0, /* Fpconst. */
+ 0, /* Neg. */
+ 0, /* Compare. */
+ 0, /* Widen. */
+ 0, /* Narrow. */
+ 0, /* Toint. */
+ 0, /* Fromint. */
+ 0 /* Roundint. */
}
},
/* Vector */
const struct tune_params arm_v7m_tune =
{
arm_9e_rtx_costs,
- &generic_extra_costs,
+ &v7m_extra_costs,
NULL, /* Sched adj cost. */
1, /* Constant limit. */
5, /* Max cond insns. */
if (TARGET_APCS_FRAME)
flag_shrink_wrap = false;
+ /* We only support -mslow-flash-data on armv7-m targets. */
+ if (target_slow_flash_data
+ && ((!(arm_arch7 && !arm_arch_notm) && !arm_arch7em)
+ || (TARGET_THUMB1 || flag_pic || TARGET_NEON)))
+ error ("-mslow-flash-data only supports non-pic code on armv7-m targets");
+
+ /* Currently, for slow flash data, we just disable literal pools. */
+ if (target_slow_flash_data)
+ arm_disable_literal_pool = true;
+
/* Register global variables with the garbage collector. */
arm_add_gc_roots ();
}
if (!crtl->uses_pic_offset_table)
{
gcc_assert (can_create_pseudo_p ());
- if (arm_pic_register != INVALID_REGNUM)
+ if (arm_pic_register != INVALID_REGNUM
+ && !(TARGET_THUMB1 && arm_pic_register > LAST_LO_REGNUM))
{
if (!cfun->machine->pic_reg)
cfun->machine->pic_reg = gen_rtx_REG (Pmode, arm_pic_register);
crtl->uses_pic_offset_table = 1;
start_sequence ();
- arm_load_pic_register (0UL);
+ if (TARGET_THUMB1 && arm_pic_register != INVALID_REGNUM
+ && arm_pic_register > LAST_LO_REGNUM)
+ emit_move_insn (cfun->machine->pic_reg,
+ gen_rtx_REG (Pmode, arm_pic_register));
+ else
+ arm_load_pic_register (0UL);
seq = get_insns ();
end_sequence ();
emit_insn (gen_movsi (pic_offset_table_rtx, pic_tmp));
emit_insn (gen_pic_add_dot_plus_four (pic_reg, pic_reg, labelno));
}
+ else if (arm_pic_register != INVALID_REGNUM
+ && arm_pic_register > LAST_LO_REGNUM
+ && REGNO (pic_reg) <= LAST_LO_REGNUM)
+ {
+ emit_insn (gen_pic_load_addr_unified (pic_reg, pic_rtx, labelno));
+ emit_move_insn (gen_rtx_REG (Pmode, arm_pic_register), pic_reg);
+ emit_use (gen_rtx_REG (Pmode, arm_pic_register));
+ }
else
emit_insn (gen_pic_load_addr_unified (pic_reg, pic_rtx, labelno));
}
&& thumb2_legitimate_index_p (mode, xop0, strict_p)));
}
+ /* Normally we can assign constant values to target registers without
+ the help of constant pool. But there are cases we have to use constant
+ pool like:
+ 1) assign a label to register.
+ 2) sign-extend a 8bit value to 32bit and then assign to register.
+
+ Constant pool access in format:
+ (set (reg r0) (mem (symbol_ref (".LC0"))))
+ will cause the use of literal pool (later in function arm_reorg).
+ So here we mark such format as an invalid format, then the compiler
+ will adjust it into:
+ (set (reg r0) (symbol_ref (".LC0")))
+ (set (reg r0) (mem (reg r0))).
+ No extra register is required, and (mem (reg r0)) won't cause the use
+ of literal pools. */
+ else if (arm_disable_literal_pool && code == SYMBOL_REF
+ && CONSTANT_POOL_ADDRESS_P (x))
+ return 0;
+
else if (GET_MODE_CLASS (mode) != MODE_FLOAT
&& code == SYMBOL_REF
&& CONSTANT_POOL_ADDRESS_P (x)
return rclass;
else
{
- if (rclass == GENERAL_REGS
- || rclass == HI_REGS
- || rclass == NO_REGS
- || rclass == STACK_REG)
+ if (rclass == GENERAL_REGS)
return LO_REGS;
else
return rclass;
if (CONSTANT_P (xop0) && !symbol_mentioned_p (xop0))
xop0 = force_reg (SImode, xop0);
- if (CONSTANT_P (xop1) && !symbol_mentioned_p (xop1))
+ if (CONSTANT_P (xop1) && !CONST_INT_P (xop1)
+ && !symbol_mentioned_p (xop1))
xop1 = force_reg (SImode, xop1);
if (ARM_BASE_REGISTER_RTX_P (xop0)
if (speed_p)
*cost += 2 * extra_cost->alu.shift;
}
+ else /* GET_MODE (XEXP (x, 0)) == SImode. */
+ *cost = COSTS_N_INSNS (1);
/* Widening beyond 32-bits requires one more insn. */
if (mode == DImode)
minipool_fix_tail = fix;
}
+/* Return maximum allowed cost of synthesizing a 64-bit constant VAL inline.
+ Returns the number of insns needed, or 99 if we always want to synthesize
+ the value. */
+int
+arm_max_const_double_inline_cost ()
+{
+ /* Let the value get synthesized to avoid the use of literal pools. */
+ if (arm_disable_literal_pool)
+ return 99;
+
+ return ((optimize_size || arm_ld_sched) ? 3 : 4);
+}
+
/* Return the cost of synthesizing a 64-bit constant VAL inline.
Returns the number of insns needed, or 99 if we don't know how to
do it. */
/* Should MOVW/MOVT be used in preference to a constant pool. */
#define TARGET_USE_MOVT \
- (arm_arch_thumb2 && !optimize_size && !current_tune->prefer_constant_pool)
+ (arm_arch_thumb2 \
+ && (arm_disable_literal_pool \
+ || (!optimize_size && !current_tune->prefer_constant_pool)))
/* We could use unified syntax for arm mode, but for now we just use it
for Thumb-2. */
than core registers. */
extern int prefer_neon_for_64bits;
+/* Nonzero if we shouldn't use literal pools. */
+#ifndef USED_FOR_TARGET
+extern bool arm_disable_literal_pool;
+#endif
+
#ifndef TARGET_DEFAULT
#define TARGET_DEFAULT (MASK_APCS_FRAME)
#endif
/* Must leave BASE_REGS reloads alone */
#define THUMB_SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, X) \
- ((CLASS) != LO_REGS && (CLASS) != BASE_REGS \
- ? ((true_regnum (X) == -1 ? LO_REGS \
- : (true_regnum (X) + HARD_REGNO_NREGS (0, MODE) > 8) ? LO_REGS \
- : NO_REGS)) \
- : NO_REGS)
+ (lra_in_progress ? NO_REGS \
+ : ((CLASS) != LO_REGS && (CLASS) != BASE_REGS \
+ ? ((true_regnum (X) == -1 ? LO_REGS \
+ : (true_regnum (X) + HARD_REGNO_NREGS (0, MODE) > 8) ? LO_REGS \
+ : NO_REGS)) \
+ : NO_REGS))
#define THUMB_SECONDARY_OUTPUT_RELOAD_CLASS(CLASS, MODE, X) \
((CLASS) != LO_REGS && (CLASS) != BASE_REGS \
;; Processor type. This is created automatically from arm-cores.def.
(include "arm-tune.md")
+;; Instruction classification types
+(include "types.md")
+
; IS_THUMB is set to 'yes' when we are generating Thumb code, and 'no' when
; generating ARM code. This is used to control the length of some insn
; patterns that share the same RTL in both ARM and Thumb code.
(const_string "yes")]
(const_string "no")))
+(define_attr "use_literal_pool" "no,yes"
+ (cond [(and (eq_attr "type" "f_loads,f_loadd")
+ (match_test "CONSTANT_P (operands[1])"))
+ (const_string "yes")]
+ (const_string "no")))
+
; Allows an insn to disable certain alternatives for reasons other than
; arch support.
(define_attr "insn_enabled" "no,yes"
(match_test "arm_restrict_it"))
(const_string "no")
+ (and (eq_attr "use_literal_pool" "yes")
+ (match_test "arm_disable_literal_pool"))
+ (const_string "no")
+
(eq_attr "arch_enabled" "no")
(const_string "no")
(set_attr "length" "4")
(set_attr "pool_range" "250")])
-;; Instruction classification types
-(include "types.md")
-
; Load scheduling, set from the arm_ld_sched variable
; initialized by arm_option_override()
(define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched")))
[(match_operand:SI 1 "s_register_operand" "r")
(match_operand:SI 2 "s_register_operand" "r")]))
(clobber (reg:CC CC_REGNUM))]
- "TARGET_32BIT && optimize_insn_for_size_p()"
+ "TARGET_32BIT && optimize_function_for_size_p (cfun)"
"*
operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
operands[1], operands[2]);
"TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
"")
+(define_insn_and_split "*zextendsidi_negsi"
+ [(set (match_operand:DI 0 "s_register_operand" "=r")
+ (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))]
+ "TARGET_32BIT"
+ "#"
+ ""
+ [(set (match_dup 2)
+ (neg:SI (match_dup 1)))
+ (set (match_dup 3)
+ (const_int 0))]
+ {
+ operands[2] = gen_lowpart (SImode, operands[0]);
+ operands[3] = gen_highpart (SImode, operands[0]);
+ }
+ [(set_attr "length" "8")
+ (set_attr "type" "multiple")]
+)
+
;; Negate an extended 32-bit value.
(define_insn_and_split "*negdi_extendsidi"
- [(set (match_operand:DI 0 "s_register_operand" "=r,&r,l,&l")
- (neg:DI (sign_extend:DI (match_operand:SI 1 "s_register_operand" "0,r,0,l"))))
+ [(set (match_operand:DI 0 "s_register_operand" "=l,r")
+ (neg:DI (sign_extend:DI
+ (match_operand:SI 1 "s_register_operand" "l,r"))))
(clobber (reg:CC CC_REGNUM))]
"TARGET_32BIT"
- "#" ; rsb\\t%Q0, %1, #0\;asr\\t%R0, %Q0, #31
+ "#"
"&& reload_completed"
[(const_int 0)]
{
- operands[2] = gen_highpart (SImode, operands[0]);
- operands[0] = gen_lowpart (SImode, operands[0]);
- rtx tmp = gen_rtx_SET (VOIDmode,
- operands[0],
- gen_rtx_MINUS (SImode,
- const0_rtx,
- operands[1]));
- if (TARGET_ARM)
- {
- emit_insn (tmp);
- }
- else
- {
- /* Set the flags, to emit the short encoding in Thumb2. */
- rtx flags = gen_rtx_SET (VOIDmode,
- gen_rtx_REG (CCmode, CC_REGNUM),
- gen_rtx_COMPARE (CCmode,
- const0_rtx,
- operands[1]));
- emit_insn (gen_rtx_PARALLEL (VOIDmode,
- gen_rtvec (2,
- flags,
- tmp)));
- }
- emit_insn (gen_rtx_SET (VOIDmode,
- operands[2],
- gen_rtx_ASHIFTRT (SImode,
- operands[0],
- GEN_INT (31))));
- DONE;
+ rtx low = gen_lowpart (SImode, operands[0]);
+ rtx high = gen_highpart (SImode, operands[0]);
+
+ if (reg_overlap_mentioned_p (low, operands[1]))
+ {
+ /* Input overlaps the low word of the output. Use:
+ asr Rhi, Rin, #31
+ rsbs Rlo, Rin, #0
+ rsc Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1). */
+ rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM);
+
+ emit_insn (gen_rtx_SET (VOIDmode, high,
+ gen_rtx_ASHIFTRT (SImode, operands[1],
+ GEN_INT (31))));
+
+ emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
+ if (TARGET_ARM)
+ emit_insn (gen_rtx_SET (VOIDmode, high,
+ gen_rtx_MINUS (SImode,
+ gen_rtx_MINUS (SImode,
+ const0_rtx,
+ high),
+ gen_rtx_LTU (SImode,
+ cc_reg,
+ const0_rtx))));
+ else
+ {
+ rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1));
+ emit_insn (gen_rtx_SET (VOIDmode, high,
+ gen_rtx_MINUS (SImode,
+ gen_rtx_MINUS (SImode,
+ high,
+ two_x),
+ gen_rtx_LTU (SImode,
+ cc_reg,
+ const0_rtx))));
+ }
+ }
+ else
+ {
+ /* No overlap, or overlap on high word. Use:
+ rsb Rlo, Rin, #0
+ bic Rhi, Rlo, Rin
+ asr Rhi, Rhi, #31
+ Flags not needed for this sequence. */
+ emit_insn (gen_rtx_SET (VOIDmode, low,
+ gen_rtx_NEG (SImode, operands[1])));
+ emit_insn (gen_rtx_SET (VOIDmode, high,
+ gen_rtx_AND (SImode,
+ gen_rtx_NOT (SImode, operands[1]),
+ low)));
+ emit_insn (gen_rtx_SET (VOIDmode, high,
+ gen_rtx_ASHIFTRT (SImode, high,
+ GEN_INT (31))));
+ }
+ DONE;
}
- [(set_attr "length" "8,8,4,4")
- (set_attr "arch" "a,a,t2,t2")
+ [(set_attr "length" "12")
+ (set_attr "arch" "t2,*")
(set_attr "type" "multiple")]
)
"TARGET_32BIT
&& reload_completed
&& (arm_const_double_inline_cost (operands[1])
- <= ((optimize_size || arm_ld_sched) ? 3 : 4))"
+ <= arm_max_const_double_inline_cost ())"
[(const_int 0)]
"
arm_split_constant (SET, SImode, curr_insn,
"
)
+;; A normal way to do (symbol + offset) requires three instructions at least
+;; (depends on how big the offset is) as below:
+;; movw r0, #:lower16:g
+;; movw r0, #:upper16:g
+;; adds r0, #4
+;;
+;; A better way would be:
+;; movw r0, #:lower16:g+4
+;; movw r0, #:upper16:g+4
+;;
+;; The limitation of this way is that the length of offset should be a 16-bit
+;; signed value, because current assembler only supports REL type relocation for
+;; such case. If the more powerful RELA type is supported in future, we should
+;; update this pattern to go with better way.
+(define_split
+ [(set (match_operand:SI 0 "arm_general_register_operand" "")
+ (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
+ (match_operand:SI 2 "const_int_operand" ""))))]
+ "TARGET_THUMB2
+ && arm_disable_literal_pool
+ && reload_completed
+ && GET_CODE (operands[1]) == SYMBOL_REF"
+ [(clobber (const_int 0))]
+ "
+ int offset = INTVAL (operands[2]);
+
+ if (offset < -0x8000 || offset > 0x7fff)
+ {
+ arm_emit_movpair (operands[0], operands[1]);
+ emit_insn (gen_rtx_SET (SImode, operands[0],
+ gen_rtx_PLUS (SImode, operands[0], operands[2])));
+ }
+ else
+ {
+ rtx op = gen_rtx_CONST (SImode,
+ gen_rtx_PLUS (SImode, operands[1], operands[2]));
+ arm_emit_movpair (operands[0], op);
+ }
+ "
+)
+
;; Split symbol_refs at the later stage (after cprop), instead of generating
;; movt/movw pair directly at expand. Otherwise corresponding high_sum
;; and lo_sum would be merged back into memory load at cprop. However,
mneon-for-64bits
Target Report RejectNegative Var(use_neon_for_64bits) Init(0)
Use Neon to perform 64-bits operations rather than core registers.
+
+mslow-flash-data
+Target Report Var(target_slow_flash_data) Init(0)
+Assume loading data from flash is slower than fetching instructions.
(UNSPEC_VRINTA "no") (UNSPEC_VRINTM "no")
(UNSPEC_VRINTR "yes") (UNSPEC_VRINTX "yes")])
+(define_int_attr vrint_conds [(UNSPEC_VRINTZ "nocond") (UNSPEC_VRINTP "unconditional")
+ (UNSPEC_VRINTA "unconditional") (UNSPEC_VRINTM "unconditional")
+ (UNSPEC_VRINTR "nocond") (UNSPEC_VRINTX "nocond")])
+
(define_int_attr nvrint_variant [(UNSPEC_NVRINTZ "z") (UNSPEC_NVRINTP "p")
(UNSPEC_NVRINTA "a") (UNSPEC_NVRINTM "m")
(UNSPEC_NVRINTX "x") (UNSPEC_NVRINTN "n")])
"vrint<vrint_variant>%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1"
[(set_attr "predicable" "<vrint_predicable>")
(set_attr "predicable_short_it" "no")
- (set_attr "type" "f_rint<vfp_type>")]
+ (set_attr "type" "f_rint<vfp_type>")
+ (set_attr "conds" "<vrint_conds>")]
)
;; MIN_EXPR and MAX_EXPR eventually map to 'smin' and 'smax' in RTL.
(match_operand:SDF 2 "register_operand" "<F_constraint>")))]
"TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 <vfp_double_cond>"
"vmaxnm.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
- [(set_attr "type" "f_minmax<vfp_type>")]
+ [(set_attr "type" "f_minmax<vfp_type>")
+ (set_attr "conds" "unconditional")]
)
(define_insn "smin<mode>3"
(match_operand:SDF 2 "register_operand" "<F_constraint>")))]
"TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 <vfp_double_cond>"
"vminnm.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
- [(set_attr "type" "f_minmax<vfp_type>")]
+ [(set_attr "type" "f_minmax<vfp_type>")
+ (set_attr "conds" "unconditional")]
)
;; Unimplemented insns:
flag_omit_frame_pointer = 0;
}
+ if (flag_pic == 1)
+ warning (OPT_fpic, "-fpic is not supported");
+ if (flag_pic == 2)
+ warning (OPT_fPIC, "-fPIC is not supported");
+ if (flag_pie == 1)
+ warning (OPT_fpie, "-fpie is not supported");
+ if (flag_pie == 2)
+ warning (OPT_fPIE, "-fPIE is not supported");
+
avr_current_device = &avr_mcu_types[avr_mcu_index];
avr_current_arch = &avr_arch_types[avr_current_device->arch];
mmcu=at90can64*|\
mmcu=at90usb64*:--pmem-wrap-around=64k}}}\
%:device_to_ld(%{mmcu=*:%*})\
-%:device_to_data_start(%{mmcu=*:%*})"
+%:device_to_data_start(%{mmcu=*:%*})\
+%{shared:%eshared is not supported}"
#define LIB_SPEC \
"%{!mmcu=at90s1*:%{!mmcu=attiny11:%{!mmcu=attiny12:%{!mmcu=attiny15:%{!mmcu=attiny28: -lc }}}}}"
extern void bfin_expand_prologue (void);
extern void bfin_expand_epilogue (int, int, bool);
-extern int push_multiple_operation (rtx, enum machine_mode);
-extern int pop_multiple_operation (rtx, enum machine_mode);
+extern int analyze_push_multiple_operation (rtx);
+extern int analyze_pop_multiple_operation (rtx);
extern void output_push_multiple (rtx, rtx *);
extern void output_pop_multiple (rtx, rtx *);
extern int bfin_hard_regno_rename_ok (unsigned int, unsigned int);
FILE *file = asm_out_file;
int i;
- fprintf (file, ".file \"%s\";\n", input_filename);
+ fprintf (file, ".file \"%s\";\n", LOCATION_FILE (input_location));
for (i = 0; arg_regs[i] >= 0; i++)
;
static int n_regs_to_save;
int
-push_multiple_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
+analyze_push_multiple_operation (rtx op)
{
int lastdreg = 8, lastpreg = 6;
int i, group;
}
int
-pop_multiple_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
+analyze_pop_multiple_operation (rtx op)
{
int lastdreg = 8, lastpreg = 6;
int i, group;
int ok;
/* Validate the insn again, and compute first_[dp]reg_to_save. */
- ok = push_multiple_operation (PATTERN (insn), VOIDmode);
+ ok = analyze_push_multiple_operation (PATTERN (insn));
gcc_assert (ok);
if (first_dreg_to_save == 8)
int ok;
/* Validate the insn again, and compute first_[dp]reg_to_save. */
- ok = pop_multiple_operation (PATTERN (insn), VOIDmode);
+ ok = analyze_pop_multiple_operation (PATTERN (insn));
gcc_assert (ok);
if (first_dreg_to_save == 8)
if (GET_CODE (pat) == PARALLEL)
{
- if (push_multiple_operation (pat, VOIDmode)
- || pop_multiple_operation (pat, VOIDmode))
+ if (analyze_push_multiple_operation (pat)
+ || analyze_pop_multiple_operation (pat))
this_cycles = n_regs_to_save;
}
else
gcc_assert (REG_P (op));
return IREG_P (op);
})
+
+(define_predicate "push_multiple_operation"
+ (and (match_code "parallel")
+ (match_test "analyze_push_multiple_operation (op)")))
+
+(define_predicate "pop_multiple_operation"
+ (and (match_code "parallel")
+ (match_test "analyze_pop_multiple_operation (op)")))
static enum machine_mode cris_promote_function_mode (const_tree, enum machine_mode,
int *, const_tree, int);
+static unsigned int cris_atomic_align_for_mode (enum machine_mode);
+
static void cris_print_base (rtx, FILE *);
static void cris_print_index (rtx, FILE *);
#undef TARGET_PROMOTE_FUNCTION_MODE
#define TARGET_PROMOTE_FUNCTION_MODE cris_promote_function_mode
+#undef TARGET_ATOMIC_ALIGN_FOR_MODE
+#define TARGET_ATOMIC_ALIGN_FOR_MODE cris_atomic_align_for_mode
+
#undef TARGET_STRUCT_VALUE_RTX
#define TARGET_STRUCT_VALUE_RTX cris_struct_value_rtx
#undef TARGET_SETUP_INCOMING_VARARGS
return CRIS_PROMOTED_MODE (mode, *punsignedp, type);
}
+/* Atomic types require alignment to be at least their "natural" size. */
+
+static unsigned int
+cris_atomic_align_for_mode (enum machine_mode mode)
+{
+ return GET_MODE_BITSIZE (mode);
+}
+
/* Let's assume all functions return in r[CRIS_FIRST_ARG_REG] for the
time being. */
#include "df.h"
#include "debug.h"
#include "obstack.h"
+#include "pointer-set.h"
+#include "hash-table.h"
+#include "vec.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-fold.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimplify.h"
#include "lto-streamer.h"
if (total_size + reg_size <= (unsigned) epiphany_stack_offset)
{
gcc_assert (first_slot < 0);
- gcc_assert (reg_size == 0 || reg_size == epiphany_stack_offset);
+ gcc_assert (reg_size == 0 || (int) reg_size == epiphany_stack_offset);
last_slot_offset = EPIPHANY_STACK_ALIGN (total_size + reg_size);
}
else
int interrupt_p;
enum epiphany_function_type fn_type;
rtx addr, mem, off, reg;
- rtx save_config;
if (!current_frame_info.initialized)
epiphany_compute_frame_size (get_frame_size ());
};
extern int epiphany_normal_fp_rounding;
+#ifndef IN_LIBGCC2
extern rtl_opt_pass *make_pass_mode_switch_use (gcc::context *ctxt);
extern rtl_opt_pass *make_pass_resolve_sw_modes (gcc::context *ctxt);
+#endif
/* This will need to be adjusted when FP_CONTRACT_ON is properly
implemented. */
LD_STATIC_OPTION " --whole-archive -ltsan --no-whole-archive " \
LD_DYNAMIC_OPTION "}}%{!static-libtsan:-ltsan}"
#endif
-
-/* Additional libraries needed by -static-libasan. */
-#undef STATIC_LIBASAN_LIBS
-#define STATIC_LIBASAN_LIBS "-ldl -lpthread"
-
-/* Additional libraries needed by -static-libtsan. */
-#undef STATIC_LIBTSAN_LIBS
-#define STATIC_LIBTSAN_LIBS "-ldl -lpthread"
;; <http://www.gnu.org/licenses/>.
;;; Unused letters:
-;;; H
+;;; B H
;;; h j
;; Integer register constraints.
(define_register_constraint "x" "TARGET_SSE ? SSE_REGS : NO_REGS"
"Any SSE register.")
-(define_register_constraint "B" "TARGET_MPX ? BND_REGS : NO_REGS"
- "@internal Any bound register.")
-
;; We use the Y prefix to denote any number of conditional register sets:
;; z First SSE register.
;; i SSE2 inter-unit moves to SSE register enabled
;; T prefix is used for different address constraints
;; v - VSIB address
;; s - address with no segment register
-;; i - address with no index and no rip
-;; b - address with no base and no rip
(define_address_constraint "Tv"
"VSIB address operand"
(define_address_constraint "Ts"
"Address operand without segment register"
(match_operand 0 "address_no_seg_operand"))
-
-(define_address_constraint "Ti"
- "MPX address operand without index"
- (match_operand 0 "address_mpx_no_index_operand"))
-
-(define_address_constraint "Tb"
- "MPX address operand without base"
- (match_operand 0 "address_mpx_no_base_operand"))
/* Atom. */
cpu = "atom";
break;
+ case 0x37:
+ case 0x4d:
+ /* Silvermont. */
+ cpu = "slm";
+ break;
case 0x0f:
/* Merom. */
case 0x17:
def_or_undef (parse_in, "__SSE_MATH__");
if ((fpmath & FPMATH_SSE) && (isa_flag & OPTION_MASK_ISA_SSE2))
def_or_undef (parse_in, "__SSE2_MATH__");
- if (isa_flag & OPTION_MASK_ISA_MPX)
- def_or_undef (parse_in, "__MPX__");
}
\f
VECTOR_MODE (INT, SI, 1); /* V1SI */
VECTOR_MODE (INT, QI, 2); /* V2QI */
-POINTER_BOUNDS_MODE (BND32, 8);
-POINTER_BOUNDS_MODE (BND64, 16);
-
INT_MODE (OI, 32);
INT_MODE (XI, 64);
extern void ix86_expand_sse2_mulvxdi3 (rtx, rtx, rtx);
extern void ix86_expand_sse2_abs (rtx, rtx);
-extern bool ix86_bnd_prefixed_insn_p (rtx);
-
/* In i386-c.c */
extern void ix86_target_macros (void);
extern void ix86_register_pragmas (void);
#include "langhooks.h"
#include "reload.h"
#include "cgraph.h"
+#include "pointer-set.h"
+#include "hash-table.h"
+#include "vec.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-fold.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimplify.h"
#include "dwarf2.h"
/* Mask registers. */
MASK_REGS, MASK_EVEX_REGS, MASK_EVEX_REGS, MASK_EVEX_REGS,
MASK_EVEX_REGS, MASK_EVEX_REGS, MASK_EVEX_REGS, MASK_EVEX_REGS,
- /* MPX bound registers */
- BND_REGS, BND_REGS, BND_REGS, BND_REGS,
};
/* The "default" register map used in 32bit mode. */
-1, -1, -1, -1, -1, -1, -1, -1, /* AVX-512 registers 16-23*/
-1, -1, -1, -1, -1, -1, -1, -1, /* AVX-512 registers 24-31*/
93, 94, 95, 96, 97, 98, 99, 100, /* Mask registers */
- 101, 102, 103, 104, /* bound registers */
};
/* The "default" register map used in 64bit mode. */
67, 68, 69, 70, 71, 72, 73, 74, /* AVX-512 registers 16-23 */
75, 76, 77, 78, 79, 80, 81, 82, /* AVX-512 registers 24-31 */
118, 119, 120, 121, 122, 123, 124, 125, /* Mask registers */
- 126, 127, 128, 129, /* bound registers */
};
/* Define the register numbers to be used in Dwarf debugging information.
-1, -1, -1, -1, -1, -1, -1, -1, /* AVX-512 registers 16-23*/
-1, -1, -1, -1, -1, -1, -1, -1, /* AVX-512 registers 24-31*/
93, 94, 95, 96, 97, 98, 99, 100, /* Mask registers */
- -1, -1, -1, -1, /* bound registers */
};
/* Define parameter passing and return registers. */
{ "-mrtm", OPTION_MASK_ISA_RTM },
{ "-mxsave", OPTION_MASK_ISA_XSAVE },
{ "-mxsaveopt", OPTION_MASK_ISA_XSAVEOPT },
- { "-mmpx", OPTION_MASK_ISA_MPX },
};
/* Flag options. */
#define PTA_AVX512ER (HOST_WIDE_INT_1 << 41)
#define PTA_AVX512PF (HOST_WIDE_INT_1 << 42)
#define PTA_AVX512CD (HOST_WIDE_INT_1 << 43)
-#define PTA_MPX (HOST_WIDE_INT_1 << 44)
/* if this reaches 64, need to widen struct pta flags below */
| PTA_SSSE3 | PTA_CX16 | PTA_MOVBE | PTA_FXSR},
{"slm", PROCESSOR_SLM, CPU_SLM,
PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3 | PTA_SSSE3
- | PTA_SSE4_1 | PTA_SSE4_2 | PTA_CX16 | PTA_POPCNT | PTA_MOVBE
- | PTA_FXSR},
+ | PTA_SSE4_1 | PTA_SSE4_2 | PTA_CX16 | PTA_POPCNT | PTA_AES
+ | PTA_PCLMUL | PTA_RDRND | PTA_MOVBE | PTA_FXSR},
{"geode", PROCESSOR_GEODE, CPU_GEODE,
PTA_MMX | PTA_3DNOW | PTA_3DNOW_A | PTA_PREFETCH_SSE | PTA_PRFCHW},
{"k6", PROCESSOR_K6, CPU_K6, PTA_MMX},
ix86_incoming_stack_boundary = ix86_default_incoming_stack_boundary;
if (opts_set->x_ix86_incoming_stack_boundary_arg)
{
- if (ix86_incoming_stack_boundary_arg
+ if (opts->x_ix86_incoming_stack_boundary_arg
< (TARGET_64BIT_P (opts->x_ix86_isa_flags) ? 4 : 2)
- || ix86_incoming_stack_boundary_arg > 12)
+ || opts->x_ix86_incoming_stack_boundary_arg > 12)
error ("-mincoming-stack-boundary=%d is not between %d and 12",
- ix86_incoming_stack_boundary_arg,
+ opts->x_ix86_incoming_stack_boundary_arg,
TARGET_64BIT_P (opts->x_ix86_isa_flags) ? 4 : 2);
else
{
ix86_user_incoming_stack_boundary
- = (1 << ix86_incoming_stack_boundary_arg) * BITS_PER_UNIT;
+ = (1 << opts->x_ix86_incoming_stack_boundary_arg) * BITS_PER_UNIT;
ix86_incoming_stack_boundary
= ix86_user_incoming_stack_boundary;
}
for (i = FIRST_MASK_REG; i <= LAST_MASK_REG; i++)
fixed_regs[i] = call_used_regs[i] = 1, reg_names[i] = "";
}
-
- /* If MPX is disabled, squash the registers. */
- if (! TARGET_MPX)
- for (i = FIRST_BND_REG; i <= LAST_BND_REG; i++)
- fixed_regs[i] = call_used_regs[i] = 1, reg_names[i] = "";
}
\f
ptr->x_ix86_isa_flags_explicit = opts->x_ix86_isa_flags_explicit;
ptr->x_ix86_target_flags_explicit = opts->x_ix86_target_flags_explicit;
ptr->x_recip_mask_explicit = opts->x_recip_mask_explicit;
+ ptr->x_ix86_arch_string = opts->x_ix86_arch_string;
+ ptr->x_ix86_tune_string = opts->x_ix86_tune_string;
+ ptr->x_ix86_cmodel = opts->x_ix86_cmodel;
+ ptr->x_ix86_abi = opts->x_ix86_abi;
+ ptr->x_ix86_asm_dialect = opts->x_ix86_asm_dialect;
+ ptr->x_ix86_branch_cost = opts->x_ix86_branch_cost;
+ ptr->x_ix86_dump_tunes = opts->x_ix86_dump_tunes;
+ ptr->x_ix86_force_align_arg_pointer = opts->x_ix86_force_align_arg_pointer;
+ ptr->x_ix86_force_drap = opts->x_ix86_force_drap;
+ ptr->x_ix86_incoming_stack_boundary_arg = opts->x_ix86_incoming_stack_boundary_arg;
+ ptr->x_ix86_pmode = opts->x_ix86_pmode;
+ ptr->x_ix86_preferred_stack_boundary_arg = opts->x_ix86_preferred_stack_boundary_arg;
+ ptr->x_ix86_recip_name = opts->x_ix86_recip_name;
+ ptr->x_ix86_regparm = opts->x_ix86_regparm;
+ ptr->x_ix86_section_threshold = opts->x_ix86_section_threshold;
+ ptr->x_ix86_sse2avx = opts->x_ix86_sse2avx;
+ ptr->x_ix86_stack_protector_guard = opts->x_ix86_stack_protector_guard;
+ ptr->x_ix86_stringop_alg = opts->x_ix86_stringop_alg;
+ ptr->x_ix86_tls_dialect = opts->x_ix86_tls_dialect;
+ ptr->x_ix86_tune_ctrl_string = opts->x_ix86_tune_ctrl_string;
+ ptr->x_ix86_tune_memcpy_strategy = opts->x_ix86_tune_memcpy_strategy;
+ ptr->x_ix86_tune_memset_strategy = opts->x_ix86_tune_memset_strategy;
+ ptr->x_ix86_tune_no_default = opts->x_ix86_tune_no_default;
+ ptr->x_ix86_veclibabi_type = opts->x_ix86_veclibabi_type;
/* The fields are char but the variables are not; make sure the
values fit in the fields. */
opts->x_ix86_isa_flags_explicit = ptr->x_ix86_isa_flags_explicit;
opts->x_ix86_target_flags_explicit = ptr->x_ix86_target_flags_explicit;
opts->x_recip_mask_explicit = ptr->x_recip_mask_explicit;
+ opts->x_ix86_arch_string = ptr->x_ix86_arch_string;
+ opts->x_ix86_tune_string = ptr->x_ix86_tune_string;
+ opts->x_ix86_cmodel = ptr->x_ix86_cmodel;
+ opts->x_ix86_abi = ptr->x_ix86_abi;
+ opts->x_ix86_asm_dialect = ptr->x_ix86_asm_dialect;
+ opts->x_ix86_branch_cost = ptr->x_ix86_branch_cost;
+ opts->x_ix86_dump_tunes = ptr->x_ix86_dump_tunes;
+ opts->x_ix86_force_align_arg_pointer = ptr->x_ix86_force_align_arg_pointer;
+ opts->x_ix86_force_drap = ptr->x_ix86_force_drap;
+ opts->x_ix86_incoming_stack_boundary_arg = ptr->x_ix86_incoming_stack_boundary_arg;
+ opts->x_ix86_pmode = ptr->x_ix86_pmode;
+ opts->x_ix86_preferred_stack_boundary_arg = ptr->x_ix86_preferred_stack_boundary_arg;
+ opts->x_ix86_recip_name = ptr->x_ix86_recip_name;
+ opts->x_ix86_regparm = ptr->x_ix86_regparm;
+ opts->x_ix86_section_threshold = ptr->x_ix86_section_threshold;
+ opts->x_ix86_sse2avx = ptr->x_ix86_sse2avx;
+ opts->x_ix86_stack_protector_guard = ptr->x_ix86_stack_protector_guard;
+ opts->x_ix86_stringop_alg = ptr->x_ix86_stringop_alg;
+ opts->x_ix86_tls_dialect = ptr->x_ix86_tls_dialect;
+ opts->x_ix86_tune_ctrl_string = ptr->x_ix86_tune_ctrl_string;
+ opts->x_ix86_tune_memcpy_strategy = ptr->x_ix86_tune_memcpy_strategy;
+ opts->x_ix86_tune_memset_strategy = ptr->x_ix86_tune_memset_strategy;
+ opts->x_ix86_tune_no_default = ptr->x_ix86_tune_no_default;
+ opts->x_ix86_veclibabi_type = ptr->x_ix86_veclibabi_type;
/* Recreate the arch feature tests if the arch changed */
if (old_arch != ix86_arch)
struct gcc_options *opts,
struct gcc_options *opts_set)
{
- const char *orig_arch_string = ix86_arch_string;
- const char *orig_tune_string = ix86_tune_string;
+ const char *orig_arch_string = opts->x_ix86_arch_string;
+ const char *orig_tune_string = opts->x_ix86_tune_string;
enum fpmath_unit orig_fpmath_set = opts_set->x_ix86_fpmath;
int orig_tune_defaulted = ix86_tune_defaulted;
int orig_arch_specified = ix86_arch_specified;
xops[0] = gen_rtx_REG (Pmode, regno);
xops[1] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
output_asm_insn ("mov%z0\t{%1, %0|%0, %1}", xops);
- output_asm_insn ("%!ret", NULL);
+ fputs ("\tret\n", asm_out_file);
final_end_function ();
init_insn_lengths ();
free_after_compilation (cfun);
xops[2] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
xops[2] = gen_rtx_MEM (QImode, xops[2]);
- output_asm_insn ("%!call\t%X2", xops);
+ output_asm_insn ("call\t%X2", xops);
#if TARGET_MACHO
/* Output the Mach-O "canonical" pic base label name ("Lxx$pb") here.
case 8:
case 4:
case 12:
- if (! ANY_FP_REG_P (x) && ! ANY_BND_REG_P (x))
+ if (! ANY_FP_REG_P (x))
putc (code == 8 && TARGET_64BIT ? 'r' : 'e', file);
/* FALLTHRU */
case 16:
~ -- print "i" if TARGET_AVX2, "f" otherwise.
@ -- print a segment register of thread base pointer load
^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
- ! -- print MPX prefix for jxx/call/ret instructions if required.
*/
void
fputs ("addr32 ", file);
return;
- case '!':
- if (ix86_bnd_prefixed_insn_p (NULL_RTX))
- fputs ("bnd ", file);
- return;
-
default:
output_operand_lossage ("invalid operand code '%c'", code);
}
ix86_print_operand_punct_valid_p (unsigned char code)
{
return (code == '@' || code == '*' || code == '+' || code == '&'
- || code == ';' || code == '~' || code == '^' || code == '!');
+ || code == ';' || code == '~' || code == '^');
}
\f
/* Print a memory operand whose address is ADDR. */
ok = ix86_decompose_address (XVECEXP (addr, 0, 0), &parts);
code = 'q';
}
- else if (GET_CODE (addr) == UNSPEC && XINT (addr, 1) == UNSPEC_BNDMK_ADDR)
- {
- ok = ix86_decompose_address (XVECEXP (addr, 0, 1), &parts);
- gcc_assert (parts.base == NULL_RTX || parts.index == NULL_RTX);
- if (parts.base != NULL_RTX)
- {
- parts.index = parts.base;
- parts.scale = 1;
- }
- parts.base = XVECEXP (addr, 0, 0);
- addr = XVECEXP (addr, 0, 0);
- }
- else if (GET_CODE (addr) == UNSPEC && XINT (addr, 1) == UNSPEC_BNDLDX_ADDR)
- {
- ok = ix86_decompose_address (XVECEXP (addr, 0, 0), &parts);
- gcc_assert (parts.index == NULL_RTX);
- parts.index = XVECEXP (addr, 0, 1);
- addr = XVECEXP (addr, 0, 0);
- }
else
ok = ix86_decompose_address (addr, &parts);
if (piece_size <= GET_MODE_SIZE (word_mode))
{
emit_insn (gen_strset (destptr, dst, promoted_val));
+ dst = adjust_automodify_address_nv (dst, move_mode, destptr,
+ piece_size);
continue;
}
{
dest = change_address (destmem, DImode, destptr);
emit_insn (gen_strset (destptr, dest, value));
+ dest = adjust_automodify_address_nv (dest, DImode, destptr, 8);
emit_insn (gen_strset (destptr, dest, value));
}
else
{
dest = change_address (destmem, SImode, destptr);
emit_insn (gen_strset (destptr, dest, value));
+ dest = adjust_automodify_address_nv (dest, SImode, destptr, 4);
emit_insn (gen_strset (destptr, dest, value));
+ dest = adjust_automodify_address_nv (dest, SImode, destptr, 8);
emit_insn (gen_strset (destptr, dest, value));
+ dest = adjust_automodify_address_nv (dest, SImode, destptr, 12);
emit_insn (gen_strset (destptr, dest, value));
}
emit_label (label);
{
dest = change_address (destmem, SImode, destptr);
emit_insn (gen_strset (destptr, dest, value));
+ dest = adjust_automodify_address_nv (dest, SImode, destptr, 4);
emit_insn (gen_strset (destptr, dest, value));
}
emit_label (label);
/* If expected size is not known but max size is small enough
so inline version is a win, set expected size into
the range. */
- if (max > 1 && (unsigned HOST_WIDE_INT)max >= max_size && expected_size == -1)
+ if (max > 1 && (unsigned HOST_WIDE_INT) max >= max_size
+ && expected_size == -1)
expected_size = min_size / 2 + max_size / 2;
/* If user specified the algorithm, honnor it if possible. */
bool noalign;
enum machine_mode move_mode = VOIDmode;
int unroll_factor = 1;
- /* TODO: Once vlaue ranges are available, fill in proper data. */
+ /* TODO: Once value ranges are available, fill in proper data. */
unsigned HOST_WIDE_INT min_size = 0;
unsigned HOST_WIDE_INT max_size = -1;
unsigned HOST_WIDE_INT probable_max_size = -1;
loop variant. */
if (issetmem && epilogue_size_needed > 2 && !promoted_val)
force_loopy_epilogue = true;
- if (count)
+ if ((count && count < (unsigned HOST_WIDE_INT) epilogue_size_needed)
+ || max_size < (unsigned HOST_WIDE_INT) epilogue_size_needed)
{
- if (count < (unsigned HOST_WIDE_INT)epilogue_size_needed)
- {
- /* If main algorithm works on QImode, no epilogue is needed.
- For small sizes just don't align anything. */
- if (size_needed == 1)
- desired_align = align;
- else
- goto epilogue;
- }
+ /* If main algorithm works on QImode, no epilogue is needed.
+ For small sizes just don't align anything. */
+ if (size_needed == 1)
+ desired_align = align;
+ else
+ goto epilogue;
}
- else if (min_size < (unsigned HOST_WIDE_INT)epilogue_size_needed)
+ else if (!count
+ && min_size < (unsigned HOST_WIDE_INT) epilogue_size_needed)
{
- gcc_assert (max_size >= (unsigned HOST_WIDE_INT)epilogue_size_needed);
label = gen_label_rtx ();
emit_cmp_and_jump_insns (count_exp,
GEN_INT (epilogue_size_needed),
if (SIBLING_CALL_P (insn))
{
if (direct_p)
- xasm = "%!jmp\t%P0";
+ xasm = "jmp\t%P0";
/* SEH epilogue detection requires the indirect branch case
to include REX.W. */
else if (TARGET_SEH)
- xasm = "%!rex.W jmp %A0";
+ xasm = "rex.W jmp %A0";
else
- xasm = "%!jmp\t%A0";
+ xasm = "jmp\t%A0";
output_asm_insn (xasm, &call_op);
return "";
}
if (direct_p)
- xasm = "%!call\t%P0";
+ xasm = "call\t%P0";
else
- xasm = "%!call\t%A0";
+ xasm = "call\t%A0";
output_asm_insn (xasm, &call_op);
{ OPTION_MASK_ISA_XOP, CODE_FOR_xop_shlv8hi3, "__builtin_ia32_vpshlw", IX86_BUILTIN_VPSHLW, UNKNOWN, (int)MULTI_ARG_2_HI },
{ OPTION_MASK_ISA_XOP, CODE_FOR_xop_shlv16qi3, "__builtin_ia32_vpshlb", IX86_BUILTIN_VPSHLB, UNKNOWN, (int)MULTI_ARG_2_QI },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_vmfrczv4sf2, "__builtin_ia32_vfrczss", IX86_BUILTIN_VFRCZSS, UNKNOWN, (int)MULTI_ARG_2_SF },
- { OPTION_MASK_ISA_XOP, CODE_FOR_xop_vmfrczv2df2, "__builtin_ia32_vfrczsd", IX86_BUILTIN_VFRCZSD, UNKNOWN, (int)MULTI_ARG_2_DF },
+ { OPTION_MASK_ISA_XOP, CODE_FOR_xop_vmfrczv4sf2, "__builtin_ia32_vfrczss", IX86_BUILTIN_VFRCZSS, UNKNOWN, (int)MULTI_ARG_1_SF },
+ { OPTION_MASK_ISA_XOP, CODE_FOR_xop_vmfrczv2df2, "__builtin_ia32_vfrczsd", IX86_BUILTIN_VFRCZSD, UNKNOWN, (int)MULTI_ARG_1_DF },
{ OPTION_MASK_ISA_XOP, CODE_FOR_xop_frczv4sf2, "__builtin_ia32_vfrczps", IX86_BUILTIN_VFRCZPS, UNKNOWN, (int)MULTI_ARG_1_SF },
{ OPTION_MASK_ISA_XOP, CODE_FOR_xop_frczv2df2, "__builtin_ia32_vfrczpd", IX86_BUILTIN_VFRCZPD, UNKNOWN, (int)MULTI_ARG_1_DF },
{ OPTION_MASK_ISA_XOP, CODE_FOR_xop_frczv8sf2, "__builtin_ia32_vfrczps256", IX86_BUILTIN_VFRCZPS256, UNKNOWN, (int)MULTI_ARG_1_SF2 },
case SSE_FIRST_REG:
case FP_TOP_REG:
case FP_SECOND_REG:
- case BND_REGS:
return true;
default:
return VALID_FP_MODE_P (mode);
if (MASK_REGNO_P (regno))
return VALID_MASK_REG_MODE (mode);
- if (BND_REGNO_P (regno))
- return VALID_BND_REG_MODE (mode);
if (SSE_REGNO_P (regno))
{
/* We implement the move patterns for all vector modes into and
for (i = FIRST_MASK_REG; i <= LAST_MASK_REG; i++)
reg_alloc_order [pos++] = i;
- /* MPX bound registers. */
- for (i = FIRST_BND_REG; i <= LAST_BND_REG; i++)
- reg_alloc_order [pos++] = i;
-
/* x87 registers. */
if (TARGET_SSE_MATH)
for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
gen_rtx_MULT (mode, op1, op2));
}
-/* Return 1 if control tansfer instruction INSN
- should be encoded with bnd prefix.
- If insn is NULL then return 1 when control
- transfer instructions should be prefixed with
- bnd by default for current function. */
-
-bool
-ix86_bnd_prefixed_insn_p (rtx insn ATTRIBUTE_UNUSED)
-{
- return false;
-}
-
/* Calculate integer abs() using only SSE2 instructions. */
void
return val;
}
+/* Set CLONEI->vecsize_mangle, CLONEI->vecsize_int,
+ CLONEI->vecsize_float and if CLONEI->simdlen is 0, also
+ CLONEI->simdlen. Return 0 if SIMD clones shouldn't be emitted,
+ or number of vecsize_mangle variants that should be emitted. */
+
+static int
+ix86_simd_clone_compute_vecsize_and_simdlen (struct cgraph_node *node,
+ struct cgraph_simd_clone *clonei,
+ tree base_type, int num)
+{
+ int ret = 1;
+
+ if (clonei->simdlen
+ && (clonei->simdlen < 2
+ || clonei->simdlen > 16
+ || (clonei->simdlen & (clonei->simdlen - 1)) != 0))
+ {
+ warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
+ "unsupported simdlen %d\n", clonei->simdlen);
+ return 0;
+ }
+
+ tree ret_type = TREE_TYPE (TREE_TYPE (node->decl));
+ if (TREE_CODE (ret_type) != VOID_TYPE)
+ switch (TYPE_MODE (ret_type))
+ {
+ case QImode:
+ case HImode:
+ case SImode:
+ case DImode:
+ case SFmode:
+ case DFmode:
+ /* case SCmode: */
+ /* case DCmode: */
+ break;
+ default:
+ warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
+ "unsupported return type %qT for simd\n", ret_type);
+ return 0;
+ }
+
+ tree t;
+ int i;
+
+ for (t = DECL_ARGUMENTS (node->decl), i = 0; t; t = DECL_CHAIN (t), i++)
+ /* FIXME: Shouldn't we allow such arguments if they are uniform? */
+ switch (TYPE_MODE (TREE_TYPE (t)))
+ {
+ case QImode:
+ case HImode:
+ case SImode:
+ case DImode:
+ case SFmode:
+ case DFmode:
+ /* case SCmode: */
+ /* case DCmode: */
+ break;
+ default:
+ warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
+ "unsupported argument type %qT for simd\n", TREE_TYPE (t));
+ return 0;
+ }
+
+ if (clonei->cilk_elemental)
+ {
+ /* Parse here processor clause. If not present, default to 'b'. */
+ clonei->vecsize_mangle = 'b';
+ }
+ else if (!TREE_PUBLIC (node->decl))
+ {
+ /* If the function isn't exported, we can pick up just one ISA
+ for the clones. */
+ if (TARGET_AVX2)
+ clonei->vecsize_mangle = 'd';
+ else if (TARGET_AVX)
+ clonei->vecsize_mangle = 'c';
+ else
+ clonei->vecsize_mangle = 'b';
+ ret = 1;
+ }
+ else
+ {
+ clonei->vecsize_mangle = "bcd"[num];
+ ret = 3;
+ }
+ switch (clonei->vecsize_mangle)
+ {
+ case 'b':
+ clonei->vecsize_int = 128;
+ clonei->vecsize_float = 128;
+ break;
+ case 'c':
+ clonei->vecsize_int = 128;
+ clonei->vecsize_float = 256;
+ break;
+ case 'd':
+ clonei->vecsize_int = 256;
+ clonei->vecsize_float = 256;
+ break;
+ }
+ if (clonei->simdlen == 0)
+ {
+ if (SCALAR_INT_MODE_P (TYPE_MODE (base_type)))
+ clonei->simdlen = clonei->vecsize_int;
+ else
+ clonei->simdlen = clonei->vecsize_float;
+ clonei->simdlen /= GET_MODE_BITSIZE (TYPE_MODE (base_type));
+ if (clonei->simdlen > 16)
+ clonei->simdlen = 16;
+ }
+ return ret;
+}
+
+/* Add target attribute to SIMD clone NODE if needed. */
+
+static void
+ix86_simd_clone_adjust (struct cgraph_node *node)
+{
+ const char *str = NULL;
+ gcc_assert (node->decl == cfun->decl);
+ switch (node->simdclone->vecsize_mangle)
+ {
+ case 'b':
+ if (!TARGET_SSE2)
+ str = "sse2";
+ break;
+ case 'c':
+ if (!TARGET_AVX)
+ str = "avx";
+ break;
+ case 'd':
+ if (!TARGET_AVX2)
+ str = "avx2";
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ if (str == NULL)
+ return;
+ push_cfun (NULL);
+ tree args = build_tree_list (NULL_TREE, build_string (strlen (str), str));
+ bool ok = ix86_valid_target_attribute_p (node->decl, NULL, args, 0);
+ gcc_assert (ok);
+ pop_cfun ();
+ ix86_previous_fndecl = NULL_TREE;
+ ix86_set_current_function (node->decl);
+}
+
+/* If SIMD clone NODE can't be used in a vectorized loop
+ in current function, return -1, otherwise return a badness of using it
+ (0 if it is most desirable from vecsize_mangle point of view, 1
+ slightly less desirable, etc.). */
+
+static int
+ix86_simd_clone_usable (struct cgraph_node *node)
+{
+ switch (node->simdclone->vecsize_mangle)
+ {
+ case 'b':
+ if (!TARGET_SSE2)
+ return -1;
+ if (!TARGET_AVX)
+ return 0;
+ return TARGET_AVX2 ? 2 : 1;
+ case 'c':
+ if (!TARGET_AVX)
+ return -1;
+ return TARGET_AVX2 ? 1 : 0;
+ break;
+ case 'd':
+ if (!TARGET_AVX2)
+ return -1;
+ return 0;
+ default:
+ gcc_unreachable ();
+ }
+}
+
/* Implement TARGET_FLOAT_EXCEPTIONS_ROUNDING_SUPPORTED_P. */
static bool
#undef TARGET_SPILL_CLASS
#define TARGET_SPILL_CLASS ix86_spill_class
+#undef TARGET_SIMD_CLONE_COMPUTE_VECSIZE_AND_SIMDLEN
+#define TARGET_SIMD_CLONE_COMPUTE_VECSIZE_AND_SIMDLEN \
+ ix86_simd_clone_compute_vecsize_and_simdlen
+
+#undef TARGET_SIMD_CLONE_ADJUST
+#define TARGET_SIMD_CLONE_ADJUST \
+ ix86_simd_clone_adjust
+
+#undef TARGET_SIMD_CLONE_USABLE
+#define TARGET_SIMD_CLONE_USABLE \
+ ix86_simd_clone_usable
+
#undef TARGET_FLOAT_EXCEPTIONS_ROUNDING_SUPPORTED_P
#define TARGET_FLOAT_EXCEPTIONS_ROUNDING_SUPPORTED_P \
ix86_float_exceptions_rounding_supported_p
#define TARGET_XSAVE_P(x) TARGET_ISA_XSAVE_P(x)
#define TARGET_XSAVEOPT TARGET_ISA_XSAVEOPT
#define TARGET_XSAVEOPT_P(x) TARGET_ISA_XSAVEOPT_P(x)
-#define TARGET_MPX TARGET_ISA_MPX
-#define TARGET_MPX_P(x) TARGET_ISA_MPX_P(x)
#define TARGET_LP64 TARGET_ABI_64
#define TARGET_LP64_P(x) TARGET_ABI_64_P(x)
eliminated during reloading in favor of either the stack or frame
pointer. */
-#define FIRST_PSEUDO_REGISTER 81
+#define FIRST_PSEUDO_REGISTER 77
/* Number of hardware registers that go into the DWARF-2 unwind info.
If not defined, equals FIRST_PSEUDO_REGISTER. */
/*xmm24,xmm25,xmm26,xmm27,xmm28,xmm29,xmm30,xmm31*/ \
0, 0, 0, 0, 0, 0, 0, 0, \
/* k0, k1, k2, k3, k4, k5, k6, k7*/ \
- 0, 0, 0, 0, 0, 0, 0, 0, \
-/* b0, b1, b2, b3*/ \
- 0, 0, 0, 0 }
+ 0, 0, 0, 0, 0, 0, 0, 0 }
/* 1 for registers not available across function calls.
These must include the FIXED_REGISTERS and also any
/*xmm24,xmm25,xmm26,xmm27,xmm28,xmm29,xmm30,xmm31*/ \
6, 6, 6, 6, 6, 6, 6, 6, \
/* k0, k1, k2, k3, k4, k5, k6, k7*/ \
- 1, 1, 1, 1, 1, 1, 1, 1, \
-/* b0, b1, b2, b3*/ \
- 1, 1, 1, 1 }
+ 1, 1, 1, 1, 1, 1, 1, 1 }
/* Order in which to allocate registers. Each register must be
listed once, even those in FIXED_REGISTERS. List frame pointer
18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, \
33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, \
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, \
- 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, \
- 78, 79, 80 }
+ 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76 }
/* ADJUST_REG_ALLOC_ORDER is a macro which permits reg_alloc_order
to be rearranged based on a particular function. When using sse math,
#define HARD_REGNO_NREGS(REGNO, MODE) \
(STACK_REGNO_P (REGNO) || SSE_REGNO_P (REGNO) || MMX_REGNO_P (REGNO) \
- || BND_REGNO_P (REGNO) \
? (COMPLEX_MODE_P (MODE) ? 2 : 1) \
: ((MODE) == XFmode \
? (TARGET_64BIT ? 2 : 3) \
|| (MODE) == V2SImode || (MODE) == SImode \
|| (MODE) == V4HImode || (MODE) == V8QImode)
-#define VALID_BND_REG_MODE(MODE) \
- (TARGET_64BIT ? (MODE) == BND64mode : (MODE) == BND32mode)
-
#define VALID_DFP_MODE_P(MODE) \
((MODE) == SDmode || (MODE) == DDmode || (MODE) == TDmode)
#define FIRST_MASK_REG (LAST_EXT_REX_SSE_REG + 1) /*69*/
#define LAST_MASK_REG (FIRST_MASK_REG + 7) /*76*/
-#define FIRST_BND_REG (LAST_MASK_REG + 1) /*77*/
-#define LAST_BND_REG (FIRST_BND_REG + 3) /*80*/
-
/* Override this in other tm.h files to cope with various OS lossage
requiring a frame pointer. */
#ifndef SUBTARGET_FRAME_POINTER_REQUIRED
SSE_FIRST_REG,
SSE_REGS,
EVEX_SSE_REGS,
- BND_REGS,
ALL_SSE_REGS,
MMX_REGS,
FP_TOP_SSE_REGS,
"SSE_FIRST_REG", \
"SSE_REGS", \
"EVEX_SSE_REGS", \
- "BND_REGS", \
"ALL_SSE_REGS", \
"MMX_REGS", \
"FP_TOP_SSE_REGS", \
TARGET_CONDITIONAL_REGISTER_USAGE. */
#define REG_CLASS_CONTENTS \
-{ { 0x00, 0x0, 0x0 }, \
- { 0x01, 0x0, 0x0 }, /* AREG */ \
- { 0x02, 0x0, 0x0 }, /* DREG */ \
- { 0x04, 0x0, 0x0 }, /* CREG */ \
- { 0x08, 0x0, 0x0 }, /* BREG */ \
- { 0x10, 0x0, 0x0 }, /* SIREG */ \
- { 0x20, 0x0, 0x0 }, /* DIREG */ \
- { 0x03, 0x0, 0x0 }, /* AD_REGS */ \
- { 0x0f, 0x0, 0x0 }, /* Q_REGS */ \
- { 0x1100f0, 0x1fe0, 0x0 }, /* NON_Q_REGS */ \
- { 0x7f, 0x1fe0, 0x0 }, /* INDEX_REGS */ \
- { 0x1100ff, 0x0, 0x0 }, /* LEGACY_REGS */ \
- { 0x07, 0x0, 0x0 }, /* CLOBBERED_REGS */ \
- { 0x1100ff, 0x1fe0, 0x0 }, /* GENERAL_REGS */ \
- { 0x100, 0x0, 0x0 }, /* FP_TOP_REG */ \
- { 0x0200, 0x0, 0x0 }, /* FP_SECOND_REG */ \
- { 0xff00, 0x0, 0x0 }, /* FLOAT_REGS */ \
- { 0x200000, 0x0, 0x0 }, /* SSE_FIRST_REG */ \
-{ 0x1fe00000, 0x1fe000, 0x0 }, /* SSE_REGS */ \
- { 0x0,0xffe00000, 0x1f }, /* EVEX_SSE_REGS */ \
- { 0x0, 0x0,0x1e000 }, /* BND_REGS */ \
-{ 0x1fe00000,0xffffe000, 0x1f }, /* ALL_SSE_REGS */ \
-{ 0xe0000000, 0x1f, 0x0 }, /* MMX_REGS */ \
-{ 0x1fe00100,0xffffe000, 0x1f }, /* FP_TOP_SSE_REG */ \
-{ 0x1fe00200,0xffffe000, 0x1f }, /* FP_SECOND_SSE_REG */ \
-{ 0x1fe0ff00,0xffffe000, 0x1f }, /* FLOAT_SSE_REGS */ \
-{ 0x11ffff, 0x1fe0, 0x0 }, /* FLOAT_INT_REGS */ \
-{ 0x1ff100ff,0xffffffe0, 0x1f }, /* INT_SSE_REGS */ \
-{ 0x1ff1ffff,0xffffffe0, 0x1f }, /* FLOAT_INT_SSE_REGS */ \
- { 0x0, 0x0, 0x1fc0 }, /* MASK_EVEX_REGS */ \
- { 0x0, 0x0, 0x1fe0 }, /* MASK_REGS */ \
-{ 0xffffffff,0xffffffff, 0x1fff } \
+{ { 0x00, 0x0, 0x0 }, \
+ { 0x01, 0x0, 0x0 }, /* AREG */ \
+ { 0x02, 0x0, 0x0 }, /* DREG */ \
+ { 0x04, 0x0, 0x0 }, /* CREG */ \
+ { 0x08, 0x0, 0x0 }, /* BREG */ \
+ { 0x10, 0x0, 0x0 }, /* SIREG */ \
+ { 0x20, 0x0, 0x0 }, /* DIREG */ \
+ { 0x03, 0x0, 0x0 }, /* AD_REGS */ \
+ { 0x0f, 0x0, 0x0 }, /* Q_REGS */ \
+ { 0x1100f0, 0x1fe0, 0x0 }, /* NON_Q_REGS */ \
+ { 0x7f, 0x1fe0, 0x0 }, /* INDEX_REGS */ \
+ { 0x1100ff, 0x0, 0x0 }, /* LEGACY_REGS */ \
+ { 0x07, 0x0, 0x0 }, /* CLOBBERED_REGS */ \
+ { 0x1100ff, 0x1fe0, 0x0 }, /* GENERAL_REGS */ \
+ { 0x100, 0x0, 0x0 }, /* FP_TOP_REG */ \
+ { 0x0200, 0x0, 0x0 }, /* FP_SECOND_REG */ \
+ { 0xff00, 0x0, 0x0 }, /* FLOAT_REGS */ \
+ { 0x200000, 0x0, 0x0 }, /* SSE_FIRST_REG */ \
+{ 0x1fe00000, 0x1fe000, 0x0 }, /* SSE_REGS */ \
+ { 0x0,0xffe00000, 0x1f }, /* EVEX_SSE_REGS */ \
+{ 0x1fe00000,0xffffe000, 0x1f }, /* ALL_SSE_REGS */ \
+{ 0xe0000000, 0x1f, 0x0 }, /* MMX_REGS */ \
+{ 0x1fe00100,0xffffe000, 0x1f }, /* FP_TOP_SSE_REG */ \
+{ 0x1fe00200,0xffffe000, 0x1f }, /* FP_SECOND_SSE_REG */ \
+{ 0x1fe0ff00,0xffffe000, 0x1f }, /* FLOAT_SSE_REGS */ \
+{ 0x11ffff, 0x1fe0, 0x0 }, /* FLOAT_INT_REGS */ \
+{ 0x1ff100ff,0xffffffe0, 0x1f }, /* INT_SSE_REGS */ \
+{ 0x1ff1ffff,0xffffffe0, 0x1f }, /* FLOAT_INT_SSE_REGS */ \
+ { 0x0, 0x0,0x1fc0 }, /* MASK_EVEX_REGS */ \
+ { 0x0, 0x0,0x1fe0 }, /* MASK_REGS */ \
+{ 0xffffffff,0xffffffff,0x1fff } \
}
/* The same information, inverted:
#define CC_REG_P(X) (REG_P (X) && CC_REGNO_P (REGNO (X)))
#define CC_REGNO_P(X) ((X) == FLAGS_REG || (X) == FPSR_REG)
-#define BND_REGNO_P(N) IN_RANGE ((N), FIRST_BND_REG, LAST_BND_REG)
-#define ANY_BND_REG_P(X) (REG_P (X) && BND_REGNO_P (REGNO (X)))
-
/* The class value for index registers, and the one for base regs. */
#define INDEX_REG_CLASS INDEX_REGS
between pointers and any other objects of this machine mode. */
#define Pmode (ix86_pmode == PMODE_DI ? DImode : SImode)
-/* Specify the machine mode that bounds have. */
-#define BNDmode (ix86_pmode == PMODE_DI ? BND64mode : BND32mode)
-
/* A C expression whose value is zero if pointers that need to be extended
from being `POINTER_SIZE' bits wide to `Pmode' are sign-extended and
greater then zero if they are zero-extended and less then zero if the
"xmm20", "xmm21", "xmm22", "xmm23", \
"xmm24", "xmm25", "xmm26", "xmm27", \
"xmm28", "xmm29", "xmm30", "xmm31", \
- "k0", "k1", "k2", "k3", "k4", "k5", "k6", "k7", \
- "bnd0", "bnd1", "bnd2", "bnd3" }
+ "k0", "k1", "k2", "k3", "k4", "k5", "k6", "k7" }
#define REGISTER_NAMES HI_REGISTER_NAMES
;; ~ -- print "i" if TARGET_AVX2, "f" otherwise.
;; @ -- print a segment register of thread base pointer load
;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
-;; ! -- print MPX prefix for jxx/call/ret instructions if required.
(define_c_enum "unspec" [
;; Relocation specifiers
;; For BMI2 support
UNSPEC_PDEP
UNSPEC_PEXT
-
- UNSPEC_BNDMK
- UNSPEC_BNDMK_ADDR
- UNSPEC_BNDSTX
- UNSPEC_BNDLDX
- UNSPEC_BNDLDX_ADDR
- UNSPEC_BNDCL
- UNSPEC_BNDCU
- UNSPEC_BNDCN
- UNSPEC_MPX_FENCE
])
(define_c_enum "unspecv" [
(MASK5_REG 74)
(MASK6_REG 75)
(MASK7_REG 76)
- (BND0_REG 77)
- (BND1_REG 78)
])
;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
ssecvt,ssecvt1,sseicvt,sseins,
sseshuf,sseshuf1,ssemuladd,sse4arg,
lwp,mskmov,msklog,
- mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft,
- mpxmov,mpxmk,mpxchk,mpxld,mpxst"
+ mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
(const_string "other"))
;; Main data type used by the insn
;; The (bounding maximum) length of an instruction immediate.
(define_attr "length_immediate" ""
(cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
- bitmanip,imulx,msklog,mskmov,mpxmk,mpxmov,mpxchk,
- mpxld,mpxst")
+ bitmanip,imulx,msklog,mskmov")
(const_int 0)
(eq_attr "unit" "i387,sse,mmx")
(const_int 0)
(const_int 0)
(and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
(const_int 1)
- (and (eq_attr "type" "ibr,call,callv")
- (match_test "ix86_bnd_prefixed_insn_p (insn)"))
- (const_int 1)
]
(const_int 0)))
;; Set when 0f opcode prefix is used.
(define_attr "prefix_0f" ""
(if_then_else
- (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov,
- mpxmk,mpxmov,mpxchk,mpxld,mpxst")
+ (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov")
(eq_attr "unit" "sse,mmx"))
(const_int 1)
(const_int 0)))
]
(const_int 1)))
-;; When this attribute is set, calculate total insn length from
-;; length_nobnd attribute, prefixed with eventual bnd prefix byte
-(define_attr "length_nobnd" "" (const_int 0))
-
;; The (bounding maximum) length of an instruction in bytes.
;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
;; Later we may want to split them and compute proper length as for
;; other insns.
(define_attr "length" ""
- (cond [(eq_attr "length_nobnd" "!0")
- (plus (symbol_ref ("ix86_bnd_prefixed_insn_p (insn)"))
- (attr "length_nobnd"))
- (eq_attr "type" "other,multi,fistp,frndint")
+ (cond [(eq_attr "type" "other,multi,fistp,frndint")
(const_int 16)
(eq_attr "type" "fcmp")
(const_int 4)
(define_attr "memory" "none,load,store,both,unknown"
(cond [(eq_attr "type" "other,multi,str,lwp")
(const_string "unknown")
- (eq_attr "type" "lea,fcmov,fpspc,mpxmk,mpxchk")
+ (eq_attr "type" "lea,fcmov,fpspc")
(const_string "none")
(eq_attr "type" "fistp,leave")
(const_string "both")
(eq_attr "type" "frndint")
(const_string "load")
- (eq_attr "type" "mpxld")
- (const_string "load")
- (eq_attr "type" "mpxst")
- (const_string "store")
(eq_attr "type" "push")
(if_then_else (match_operand 1 "memory_operand")
(const_string "both")
fmov,fcmp,fsgn,
sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
- mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog,mpxmov")
+ mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog")
(match_operand 2 "memory_operand"))
(const_string "load")
(and (eq_attr "type" "icmov,ssemuladd,sse4arg")
(define_mode_iterator DWIH [(SI "!TARGET_64BIT")
(DI "TARGET_64BIT")])
-;; Bound modes.
-(define_mode_iterator BND [(BND32 "!TARGET_LP64")
- (BND64 "TARGET_LP64")])
-
-;; Pointer mode corresponding to bound mode.
-(define_mode_attr bnd_ptr [(BND32 "SI") (BND64 "DI")])
-
-;; MPX check types
-(define_int_iterator BNDCHECK [UNSPEC_BNDCL UNSPEC_BNDCU UNSPEC_BNDCN])
-
-;; Check name
-(define_int_attr bndcheck [(UNSPEC_BNDCL "cl")
- (UNSPEC_BNDCU "cu")
- (UNSPEC_BNDCN "cn")])
-
;; Instruction suffix for integer modes.
(define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
(label_ref (match_operand 0))
(pc)))]
""
- "%!%+j%C1\t%l0"
+ "%+j%C1\t%l0"
[(set_attr "type" "ibr")
(set_attr "modrm" "0")
- (set (attr "length_nobnd")
+ (set (attr "length")
(if_then_else (and (ge (minus (match_dup 0) (pc))
(const_int -126))
(lt (minus (match_dup 0) (pc))
(pc)
(label_ref (match_operand 0))))]
""
- "%!%+j%c1\t%l0"
+ "%+j%c1\t%l0"
[(set_attr "type" "ibr")
(set_attr "modrm" "0")
- (set (attr "length_nobnd")
+ (set (attr "length")
(if_then_else (and (ge (minus (match_dup 0) (pc))
(const_int -126))
(lt (minus (match_dup 0) (pc))
[(set (pc)
(label_ref (match_operand 0)))]
""
- "%!jmp\t%l0"
+ "jmp\t%l0"
[(set_attr "type" "ibr")
- (set (attr "length_nobnd")
+ (set (attr "length")
(if_then_else (and (ge (minus (match_dup 0) (pc))
(const_int -126))
(lt (minus (match_dup 0) (pc))
(define_insn "*indirect_jump"
[(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))]
""
- "%!jmp\t%A0"
+ "jmp\t%A0"
[(set_attr "type" "ibr")
(set_attr "length_immediate" "0")])
[(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))
(use (label_ref (match_operand 1)))]
""
- "%!jmp\t%A0"
+ "jmp\t%A0"
[(set_attr "type" "ibr")
(set_attr "length_immediate" "0")])
\f
(define_insn "simple_return_internal"
[(simple_return)]
"reload_completed"
- "%!ret"
- [(set_attr "length_nobnd" "1")
+ "ret"
+ [(set_attr "length" "1")
(set_attr "atom_unit" "jeu")
(set_attr "length_immediate" "0")
(set_attr "modrm" "0")])
[(simple_return)
(unspec [(const_int 0)] UNSPEC_REP)]
"reload_completed"
-{
- if (ix86_bnd_prefixed_insn_p (insn))
- return "%!ret";
-
- return "rep%; ret";
-}
+ "rep%; ret"
[(set_attr "length" "2")
(set_attr "atom_unit" "jeu")
(set_attr "length_immediate" "0")
[(simple_return)
(use (match_operand:SI 0 "const_int_operand"))]
"reload_completed"
- "%!ret\t%0"
- [(set_attr "length_nobnd" "3")
+ "ret\t%0"
+ [(set_attr "length" "3")
(set_attr "atom_unit" "jeu")
(set_attr "length_immediate" "2")
(set_attr "modrm" "0")])
[(simple_return)
(use (match_operand:SI 0 "register_operand" "r"))]
"reload_completed"
- "%!jmp\t%A0"
+ "jmp\t%A0"
[(set_attr "type" "ibr")
(set_attr "length_immediate" "0")])
[(set_attr "type" "other")
(set_attr "length" "3")])
-;; MPX instructions
-
-(define_expand "<mode>_mk"
- [(set (match_operand:BND 0 "register_operand")
- (unspec:BND
- [(mem:<bnd_ptr>
- (match_par_dup 3
- [(match_operand:<bnd_ptr> 1 "register_operand")
- (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand")]))]
- UNSPEC_BNDMK))]
- "TARGET_MPX"
-{
- operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
- operands[2]),
- UNSPEC_BNDMK_ADDR);
-})
-
-(define_insn "*<mode>_mk"
- [(set (match_operand:BND 0 "register_operand" "=B")
- (unspec:BND
- [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
- [(unspec:<bnd_ptr>
- [(match_operand:<bnd_ptr> 1 "register_operand" "r")
- (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand" "Tb")]
- UNSPEC_BNDMK_ADDR)])]
- UNSPEC_BNDMK))]
- "TARGET_MPX"
- "bndmk\t{%3, %0|%0, %3}"
- [(set_attr "type" "mpxmk")])
-
-(define_expand "mov<mode>"
- [(set (match_operand:BND 0 "general_operand")
- (match_operand:BND 1 "general_operand"))]
- "TARGET_MPX"
-{
- ix86_expand_move (<MODE>mode, operands);DONE;
-})
-
-(define_insn "*mov<mode>_internal_mpx"
- [(set (match_operand:BND 0 "nonimmediate_operand" "=B,m")
- (match_operand:BND 1 "general_operand" "Bm,B"))]
- "TARGET_MPX"
- "bndmov\t{%1, %0|%0, %1}"
- [(set_attr "type" "mpxmov")])
-
-(define_expand "<mode>_<bndcheck>"
- [(parallel [(unspec [(match_operand:BND 0 "register_operand")
- (match_operand:<bnd_ptr> 1 "address_no_seg_operand")] BNDCHECK)
- (set (match_dup 2)
- (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
- "TARGET_MPX"
-{
- operands[2] = gen_rtx_MEM (BLKmode, operands[1]);
- MEM_VOLATILE_P (operands[2]) = 1;
-})
-
-(define_insn "*<mode>_<bndcheck>"
- [(parallel [(unspec [(match_operand:BND 0 "register_operand" "B")
- (match_operand:<bnd_ptr> 1 "address_no_seg_operand" "Ts")] BNDCHECK)
- (set (match_operand:BLK 2 "bnd_mem_operator")
- (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
- "TARGET_MPX"
- "bnd<bndcheck>\t{%a1, %0|%0, %a1}"
- [(set_attr "type" "mpxchk")])
-
-(define_expand "<mode>_ldx"
- [(parallel [(set:BND (match_operand:BND 0 "register_operand")
- (unspec:BND
- [(mem:<bnd_ptr>
- (match_par_dup 3
- [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand")
- (match_operand:<bnd_ptr> 2 "register_operand")]))]
- UNSPEC_BNDLDX))
- (use (mem:BLK (match_dup 1)))])]
- "TARGET_MPX"
-{
- operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
- operands[2]),
- UNSPEC_BNDLDX_ADDR);
-})
-
-(define_insn "*<mode>_ldx"
- [(parallel [(set:BND (match_operand:BND 0 "register_operand" "=B")
- (unspec:BND
- [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
- [(unspec:<bnd_ptr>
- [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand" "Ti")
- (match_operand:<bnd_ptr> 2 "register_operand" "l")]
- UNSPEC_BNDLDX_ADDR)])]
- UNSPEC_BNDLDX))
- (use (mem:BLK (match_dup 1)))])]
- "TARGET_MPX"
- "bndldx\t{%3, %0|%0, %3}"
- [(set_attr "type" "mpxld")])
-
-(define_expand "<mode>_stx"
- [(parallel [(unspec [(mem:<bnd_ptr>
- (match_par_dup 3
- [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand")
- (match_operand:<bnd_ptr> 1 "register_operand")]))
- (match_operand:BND 2 "register_operand")] UNSPEC_BNDSTX)
- (set (match_dup 4)
- (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
- "TARGET_MPX"
-{
- operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[0],
- operands[1]),
- UNSPEC_BNDLDX_ADDR);
- operands[4] = gen_rtx_MEM (BLKmode, operands[0]);
- MEM_VOLATILE_P (operands[4]) = 1;
-})
-
-(define_insn "*<mode>_stx"
- [(parallel [(unspec [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
- [(unspec:<bnd_ptr>
- [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand" "Ti")
- (match_operand:<bnd_ptr> 1 "register_operand" "l")]
- UNSPEC_BNDLDX_ADDR)])
- (match_operand:BND 2 "register_operand" "B")] UNSPEC_BNDSTX)
- (set (match_operand:BLK 4 "bnd_mem_operator")
- (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
- "TARGET_MPX"
- "bndstx\t{%2, %3|%3, %2}"
- [(set_attr "type" "mpxst")])
-
(include "mmx.md")
(include "sse.md")
(include "sync.md")
TargetSave
unsigned char tune
+;; -march= processor-string
+TargetSave
+const char *x_ix86_arch_string
+
+;; -mtune= processor-string
+TargetSave
+const char *x_ix86_tune_string
+
;; CPU schedule model
TargetSave
unsigned char schedule
TargetSave
unsigned char arch_specified
+;; -mcmodel= model
+TargetSave
+enum cmodel x_ix86_cmodel
+
+;; -mabi=
+TargetSave
+enum calling_abi x_ix86_abi
+
+;; -masm=
+TargetSave
+enum asm_dialect x_ix86_asm_dialect
+
+;; -mbranch-cost=
+TargetSave
+int x_ix86_branch_cost
+
+;; -mdump-tune-features=
+TargetSave
+int x_ix86_dump_tunes
+
+;; -mstackrealign=
+TargetSave
+int x_ix86_force_align_arg_pointer
+
+;; -mforce-drap=
+TargetSave
+int x_ix86_force_drap
+
+;; -mincoming-stack-boundary=
+TargetSave
+int x_ix86_incoming_stack_boundary_arg
+
+;; -maddress-mode=
+TargetSave
+enum pmode x_ix86_pmode
+
+;; -mpreferred-stack-boundary=
+TargetSave
+int x_ix86_preferred_stack_boundary_arg
+
+;; -mrecip=
+TargetSave
+const char *x_ix86_recip_name
+
+;; -mregparm=
+TargetSave
+int x_ix86_regparm
+
+;; -mlarge-data-threshold=
+TargetSave
+int x_ix86_section_threshold
+
+;; -msse2avx=
+TargetSave
+int x_ix86_sse2avx
+
+;; -mstack-protector-guard=
+TargetSave
+enum stack_protector_guard x_ix86_stack_protector_guard
+
+;; -mstringop-strategy=
+TargetSave
+enum stringop_alg x_ix86_stringop_alg
+
+;; -mtls-dialect=
+TargetSave
+enum tls_dialect x_ix86_tls_dialect
+
+;; -mtune-ctrl=
+TargetSave
+const char *x_ix86_tune_ctrl_string
+
+;; -mmemcpy-strategy=
+TargetSave
+const char *x_ix86_tune_memcpy_strategy
+
+;; -mmemset-strategy=
+TargetSave
+const char *x_ix86_tune_memset_strategy
+
+;; -mno-default=
+TargetSave
+int x_ix86_tune_no_default
+
+;; -mveclibabi=
+TargetSave
+enum ix86_veclibabi x_ix86_veclibabi_type
+
;; x86 options
m128bit-long-double
Target RejectNegative Report Mask(128BIT_LONG_DOUBLE) Save
Target Report Mask(ISA_RTM) Var(ix86_isa_flags) Save
Support RTM built-in functions and code generation
-mmpx
-Target Report Mask(ISA_MPX) Var(ix86_isa_flags) Save
-Support MPX code generation
-
mstack-protector-guard=
Target RejectNegative Joined Enum(stack_protector_guard) Var(ix86_stack_protector_guard) Init(SSP_TLS)
Use given stack-protector guard
return true;
})
-;; Return true if op is valid MPX address operand without base
-(define_predicate "address_mpx_no_base_operand"
- (match_operand 0 "address_operand")
-{
- struct ix86_address parts;
- int ok;
-
- ok = ix86_decompose_address (op, &parts);
- gcc_assert (ok);
-
- if (parts.index && parts.base)
- return false;
-
- if (parts.seg != SEG_DEFAULT)
- return false;
-
- /* Do not support (%rip). */
- if (parts.disp && flag_pic && TARGET_64BIT
- && SYMBOLIC_CONST (parts.disp))
- {
- if (GET_CODE (parts.disp) != CONST
- || GET_CODE (XEXP (parts.disp, 0)) != PLUS
- || GET_CODE (XEXP (XEXP (parts.disp, 0), 0)) != UNSPEC
- || !CONST_INT_P (XEXP (XEXP (parts.disp, 0), 1))
- || (XINT (XEXP (XEXP (parts.disp, 0), 0), 1) != UNSPEC_DTPOFF
- && XINT (XEXP (XEXP (parts.disp, 0), 0), 1) != UNSPEC_NTPOFF))
- return false;
- }
-
- return true;
-})
-
-;; Return true if op is valid MPX address operand without index
-(define_predicate "address_mpx_no_index_operand"
- (match_operand 0 "address_operand")
-{
- struct ix86_address parts;
- int ok;
-
- ok = ix86_decompose_address (op, &parts);
- gcc_assert (ok);
-
- if (parts.index)
- return false;
-
- if (parts.seg != SEG_DEFAULT)
- return false;
-
- /* Do not support (%rip). */
- if (parts.disp && flag_pic && TARGET_64BIT
- && SYMBOLIC_CONST (parts.disp)
- && (GET_CODE (parts.disp) != CONST
- || GET_CODE (XEXP (parts.disp, 0)) != PLUS
- || GET_CODE (XEXP (XEXP (parts.disp, 0), 0)) != UNSPEC
- || !CONST_INT_P (XEXP (XEXP (parts.disp, 0), 1))
- || (XINT (XEXP (XEXP (parts.disp, 0), 0), 1) != UNSPEC_DTPOFF
- && XINT (XEXP (XEXP (parts.disp, 0), 0), 1) != UNSPEC_NTPOFF)))
- return false;
-
- return true;
-})
-
(define_predicate "vsib_mem_operator"
(match_code "mem"))
-(define_predicate "bnd_mem_operator"
- (match_code "mem"))
-
;; Return true if the rtx is known to be at least 32 bits aligned.
(define_predicate "aligned_operand"
(match_operand 0 "general_operand")
[(set_attr "type" "ssecvt1")
(set_attr "mode" "<MODE>")])
-;; scalar insns
(define_expand "xop_vmfrcz<mode>2"
[(set (match_operand:VF_128 0 "register_operand")
(vec_merge:VF_128
(match_dup 3)
(const_int 1)))]
"TARGET_XOP"
-{
- operands[3] = CONST0_RTX (<MODE>mode);
-})
+ "operands[3] = CONST0_RTX (<MODE>mode);")
-(define_insn "*xop_vmfrcz_<mode>"
+(define_insn "*xop_vmfrcz<mode>2"
[(set (match_operand:VF_128 0 "register_operand" "=x")
(vec_merge:VF_128
(unspec:VF_128
#include "ggc.h"
#include "target.h"
#include "except.h"
+#include "pointer-set.h"
+#include "hash-table.h"
+#include "vec.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-fold.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "lto-streamer.h"
flags |= SECTION_LINKONCE;
/* See if we already have an entry for this section. */
- slot = htab.find_slot ((unsigned int *)name, INSERT);
+ slot = htab.find_slot ((const unsigned int *)name, INSERT);
if (!*slot)
{
*slot = (unsigned int *) xmalloc (sizeof (unsigned int));
sets 'discard' characteristic, rather than telling linker
to warn of size or content mismatch, so do the same. */
bool discard = (flags & SECTION_CODE)
- || lookup_attribute ("selectany",
- DECL_ATTRIBUTES (decl));
+ || (TREE_CODE (decl) != IDENTIFIER_NODE
+ && lookup_attribute ("selectany",
+ DECL_ATTRIBUTES (decl)));
fprintf (asm_out_file, "\t.linkonce %s\n",
(discard ? "discard" : "same_size"));
}
extern __inline __m128 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_frcz_ss (__m128 __A, __m128 __B)
{
- return (__m128) __builtin_ia32_vfrczss ((__v4sf)__A, (__v4sf)__B);
+ return (__m128) __builtin_ia32_movss ((__v4sf)__A,
+ (__v4sf)
+ __builtin_ia32_vfrczss ((__v4sf)__B));
}
extern __inline __m128d __attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_frcz_sd (__m128d __A, __m128d __B)
{
- return (__m128d) __builtin_ia32_vfrczsd ((__v2df)__A, (__v2df)__B);
+ return (__m128d) __builtin_ia32_movsd ((__v2df)__A,
+ (__v2df)
+ __builtin_ia32_vfrczsd ((__v2df)__B));
}
extern __inline __m256 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
/* ia64 HPUX has the float and long double forms of math functions.
We redefine this hook so the version from elfos.h header won't be used. */
#undef TARGET_LIBC_HAS_FUNCTION
-#define TARGET_LIBC_HAS_FUNCTION default_c99_libc_has_function
+#define TARGET_LIBC_HAS_FUNCTION default_libc_has_function
#undef TARGET_INIT_LIBFUNCS
#define TARGET_INIT_LIBFUNCS ia64_hpux_init_libfuncs
#include "tm_p.h"
#include "hash-table.h"
#include "langhooks.h"
+#include "pointer-set.h"
+#include "vec.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-fold.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimplify.h"
#include "intl.h"
#include "target-def.h"
#include "tm_p.h"
#include "langhooks.h"
+#include "pointer-set.h"
+#include "hash-table.h"
+#include "vec.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-fold.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "df.h"
#include "tm-constrs.h"
#include "target-def.h"
#include "langhooks.h"
#include "df.h"
+#include "pointer-set.h"
+#include "hash-table.h"
+#include "vec.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-fold.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimplify.h"
#include "opts.h"
#include "common/common-target.h"
#include "langhooks.h"
#include "sched-int.h"
+#include "pointer-set.h"
+#include "vec.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-fold.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimplify.h"
#include "bitmap.h"
extern void mn10300_print_operand_address (FILE *, rtx);
extern void mn10300_print_reg_list (FILE *, int);
extern enum machine_mode mn10300_select_cc_mode (enum rtx_code, rtx, rtx);
-extern int mn10300_store_multiple_operation (rtx, enum machine_mode);
+extern int mn10300_store_multiple_operation_p (rtx);
extern int mn10300_symbolic_operand (rtx, enum machine_mode);
extern void mn10300_split_cbranch (enum machine_mode, rtx, rtx);
extern int mn10300_split_and_operand_count (rtx);
registers it saves. Return 0 otherwise. */
int
-mn10300_store_multiple_operation (rtx op,
- enum machine_mode mode ATTRIBUTE_UNUSED)
+mn10300_store_multiple_operation_p (rtx op)
{
int count;
int mask;
(define_predicate "liw_operand"
(ior (match_operand 0 "register_operand")
(match_test "satisfies_constraint_O (op)")))
+
+(define_predicate "mn10300_store_multiple_operation"
+ (and (match_code "parallel")
+ (match_test "mn10300_store_multiple_operation_p (op)")))
break;
case MULT:
- *total = COSTS_N_INSNS (5);
+ *total = COSTS_N_INSNS (1);
break;
case DIV:
collect has a chance to see them, so scan the object files directly. */
#define COLLECT_EXPORT_LIST
+/* On AIX, initialisers specified with -binitfini are called in breadth-first
+ order.
+ e.g. if a.out depends on lib1.so, the init function for a.out is called before
+ the init function for lib1.so.
+
+ To ensure global C++ constructors in linked libraries are run before global
+ C++ constructors from the current module, there is additional symbol scanning
+ logic in collect2.
+
+ The global initialiser/finaliser functions are named __GLOBAL_AIXI_{libname}
+ and __GLOBAL_AIXD_{libname} and are exported from each shared library.
+
+ collect2 will detect these symbols when they exist in shared libraries that
+ the current program is being linked against. All such initiliser functions
+ will be called prior to the constructors of the current program, and
+ finaliser functions called after destructors.
+
+ Reference counting generated by collect2 will ensure that constructors are
+ only invoked once in the case of multiple dependencies on a library.
+
+ -binitfini is still used in parallel to this solution.
+ This handles the case where a library is loaded through dlopen(), and also
+ handles the option -blazy.
+*/
+#define COLLECT_SHARED_INIT_FUNC(STREAM, FUNC) \
+ fprintf ((STREAM), "void %s() {\n\t%s();\n}\n", aix_shared_initname, (FUNC))
+#define COLLECT_SHARED_FINI_FUNC(STREAM, FUNC) \
+ fprintf ((STREAM), "void %s() {\n\t%s();\n}\n", aix_shared_fininame, (FUNC))
+
#if HAVE_AS_REF
/* Issue assembly directives that create a reference to the given DWARF table
identifier label from the current function section. This is defined to
#define _TEXASRU_IMPLEMENTAION_SPECIFIC(TEXASRU) \
_TEXASRU_EXTRACT_BITS(TEXASRU, 15, 1)
-#define _TEXASR_INSRUCTION_FETCH_CONFLICT(TEXASR) \
+#define _TEXASR_INSTRUCTION_FETCH_CONFLICT(TEXASR) \
_TEXASR_EXTRACT_BITS(TEXASR, 16, 1)
-#define _TEXASRU_INSRUCTION_FETCH_CONFLICT(TEXASRU) \
+#define _TEXASRU_INSTRUCTION_FETCH_CONFLICT(TEXASRU) \
_TEXASRU_EXTRACT_BITS(TEXASRU, 16, 1)
#define _TEXASR_ABORT(TEXASR) \
#include "reload.h"
#include "cfgloop.h"
#include "sched-int.h"
+#include "pointer-set.h"
+#include "hash-table.h"
+#include "vec.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-fold.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimplify.h"
#include "gimple-iterator.h"
name, suffix[smclass], flags & SECTION_ENTSIZE);
}
+#define IN_NAMED_SECTION(DECL) \
+ ((TREE_CODE (DECL) == FUNCTION_DECL || TREE_CODE (DECL) == VAR_DECL) \
+ && DECL_SECTION_NAME (DECL) != NULL_TREE)
+
static section *
rs6000_xcoff_select_section (tree decl, int reloc,
- unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
+ unsigned HOST_WIDE_INT align)
{
+ /* Place variables with alignment stricter than BIGGEST_ALIGNMENT into
+ named section. */
+ if (align > BIGGEST_ALIGNMENT)
+ {
+ resolve_unique_section (decl, reloc, true);
+ if (IN_NAMED_SECTION (decl))
+ return get_named_section (decl, NULL, reloc);
+ }
+
if (decl_readonly_section (decl, reloc))
{
if (TREE_PUBLIC (decl))
{
const char *name;
- /* Use select_section for private and uninitialized data. */
+ /* Use select_section for private data and uninitialized data with
+ alignment <= BIGGEST_ALIGNMENT. */
if (!TREE_PUBLIC (decl)
|| DECL_COMMON (decl)
- || DECL_INITIAL (decl) == NULL_TREE
+ || (DECL_INITIAL (decl) == NULL_TREE
+ && DECL_ALIGN (decl) <= BIGGEST_ALIGNMENT)
|| DECL_INITIAL (decl) == error_mark_node
|| (flag_zero_initialized_in_bss
&& initializer_zerop (DECL_INITIAL (decl))))
gcc_assert (GET_MODE_NUNITS (vmode) == 2);
dmode = mode_for_vector (GET_MODE_INNER (vmode), 4);
+ /* For little endian, swap operands and invert/swap selectors
+ to get the correct xxpermdi. The operand swap sets up the
+ inputs as a little endian array. The selectors are swapped
+ because they are defined to use big endian ordering. The
+ selectors are inverted to get the correct doublewords for
+ little endian ordering. */
+ if (!BYTES_BIG_ENDIAN)
+ {
+ int n;
+ perm0 = 3 - perm0;
+ perm1 = 3 - perm1;
+ n = perm0, perm0 = perm1, perm1 = n;
+ x = op0, op0 = op1, op1 = x;
+ }
+
x = gen_rtx_VEC_CONCAT (dmode, op0, op1);
v = gen_rtvec (2, GEN_INT (perm0), GEN_INT (perm1));
x = gen_rtx_VEC_SELECT (vmode, x, gen_rtx_PARALLEL (VOIDmode, v));
(set (match_operand:VSX_M2 2 "vsx_register_operand" "")
(mem:VSX_M2 (plus:P (match_dup 0)
(match_operand:P 3 "int_reg_operand" ""))))]
- "TARGET_P8_FUSION"
+ "TARGET_VSX && TARGET_P8_FUSION"
"li %0,%1\t\t\t# vector load fusion\;lx<VSX_M2:VSm>x %x2,%0,%3"
[(set_attr "length" "8")
(set_attr "type" "vecload")])
(set (match_operand:VSX_M2 2 "vsx_register_operand" "")
(mem:VSX_M2 (plus:P (match_operand:P 3 "int_reg_operand" "")
(match_dup 0))))]
- "TARGET_P8_FUSION"
+ "TARGET_VSX && TARGET_P8_FUSION"
"li %0,%1\t\t\t# vector load fusion\;lx<VSX_M2:VSm>x %x2,%0,%3"
[(set_attr "length" "8")
(set_attr "type" "vecload")])
#include "debug.h"
#include "langhooks.h"
#include "optabs.h"
+#include "pointer-set.h"
+#include "hash-table.h"
+#include "vec.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-fold.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimplify.h"
#include "df.h"
/* The class value for index registers. */
#define INDEX_REG_CLASS NO_REGS
-extern enum reg_class score_char_to_class[256];
-#define REG_CLASS_FROM_LETTER(C) score_char_to_class[(unsigned char) (C)]
-
/* Addressing modes, and classification of registers for them. */
#define REGNO_MODE_OK_FOR_BASE_P(REGNO, MODE) \
score_regno_mode_ok_for_base_p (REGNO, 1)
(define_constraint "Q"
"A pc relative load operand."
(and (match_code "mem")
+ (match_test "GET_MODE (op) != QImode")
(match_test "IS_PC_RELATIVE_LOAD_ADDR_P (XEXP (op, 0))")))
(define_constraint "Bsc"
(define_memory_constraint "Sdd"
"A memory reference that uses displacement addressing."
- (and (match_test "MEM_P (op) && GET_CODE (XEXP (op, 0)) == PLUS")
+ (and (match_code "mem")
+ (match_test "GET_CODE (XEXP (op, 0)) == PLUS")
(match_test "REG_P (XEXP (XEXP (op, 0), 0))")
(match_test "CONST_INT_P (XEXP (XEXP (op, 0), 1))")))
(define_memory_constraint "Snd"
"A memory reference that excludes displacement addressing."
- (match_test "! satisfies_constraint_Sdd (op)"))
+ (and (match_code "mem")
+ (match_test "! satisfies_constraint_Sdd (op)")))
(define_memory_constraint "Sbv"
"A memory reference, as used in SH2A bclr.b, bset.b, etc."
XEXP (XEXP (op, 0), 1),
TARGET_SH2A, true)")))
+;; Returns true if OP is a displacement address that can fit into a
+;; 16 bit (non-SH2A) memory load / store insn.
+(define_predicate "short_displacement_mem_operand"
+ (match_test "sh_disp_addr_displacement (op)
+ <= sh_max_mov_insn_displacement (GET_MODE (op), false)"))
+
;; Returns 1 if the operand can be used in an SH2A movu.{b|w} insn.
(define_predicate "zero_extend_movu_operand"
(and (match_operand 0 "displacement_mem_operand")
if (t_reg_operand (op, mode))
return 0;
+ /* Disallow PC relative QImode loads, since these is no insn to do that
+ and an imm8 load should be used instead. */
+ if (IS_PC_RELATIVE_LOAD_ADDR_P (op) && GET_MODE (op) == QImode)
+ return false;
+
if (MEM_P (op))
{
rtx inside = XEXP (op, 0);
extern bool sh_cfun_trap_exit_p (void);
extern rtx sh_find_equiv_gbr_addr (rtx cur_insn, rtx mem);
extern int sh_eval_treg_value (rtx op);
+extern HOST_WIDE_INT sh_disp_addr_displacement (rtx mem_op);
+extern int sh_max_mov_insn_displacement (machine_mode mode, bool consider_sh2a);
/* Result value of sh_find_set_of_reg. */
struct set_of_reg
#include "sched-int.h"
#include "params.h"
#include "ggc.h"
+#include "pointer-set.h"
+#include "hash-table.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-fold.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimplify.h"
#include "cfgloop.h"
static void sh_conditional_register_usage (void);
static bool sh_legitimate_constant_p (enum machine_mode, rtx);
static int mov_insn_size (enum machine_mode, bool);
-static int max_mov_insn_displacement (enum machine_mode, bool);
static int mov_insn_alignment_mask (enum machine_mode, bool);
-static HOST_WIDE_INT disp_addr_displacement (rtx);
static bool sequence_insn_p (rtx);
static void sh_canonicalize_comparison (int *, rtx *, rtx *, bool);
static void sh_canonicalize_comparison (enum rtx_code&, rtx&, rtx&,
/* Determine the maximum possible displacement for a move insn for the
specified mode. */
-static int
-max_mov_insn_displacement (enum machine_mode mode, bool consider_sh2a)
+int
+sh_max_mov_insn_displacement (machine_mode mode, bool consider_sh2a)
{
/* The 4 byte displacement move insns are the same as the 2 byte
versions but take a 12 bit displacement. All we need to do is to
}
/* Return the displacement value of a displacement address. */
-static inline HOST_WIDE_INT
-disp_addr_displacement (rtx x)
+HOST_WIDE_INT
+sh_disp_addr_displacement (rtx x)
{
gcc_assert (satisfies_constraint_Sdd (x));
return INTVAL (XEXP (XEXP (x, 0), 1));
HImode and QImode loads/stores with displacement put pressure on
R0 which will most likely require another reg copy. Thus account
a higher cost for that. */
- if (offset > 0 && offset <= max_mov_insn_displacement (mode, false))
+ if (offset > 0 && offset <= sh_max_mov_insn_displacement (mode, false))
return (mode == HImode || mode == QImode) ? 2 : 1;
/* The displacement would fit into a 4 byte move insn (SH2A). */
if (TARGET_SH2A
- && offset > 0 && offset <= max_mov_insn_displacement (mode, true))
+ && offset > 0 && offset <= sh_max_mov_insn_displacement (mode, true))
return 2;
/* The displacement is probably out of range and will require extra
else
{
const HOST_WIDE_INT offset = INTVAL (op);
- const int max_disp = max_mov_insn_displacement (mode, consider_sh2a);
+ const int max_disp = sh_max_mov_insn_displacement (mode, consider_sh2a);
const int align_mask = mov_insn_alignment_mask (mode, consider_sh2a);
/* If the mode does not support any displacement always return false.
effectively disable the small displacement insns. */
const int mode_sz = GET_MODE_SIZE (mode);
const int mov_insn_sz = mov_insn_size (mode, false);
- const int max_disp = max_mov_insn_displacement (mode, false);
+ const int max_disp = sh_max_mov_insn_displacement (mode, false);
const int max_disp_next = max_disp + mov_insn_sz;
HOST_WIDE_INT align_modifier = offset > 127 ? mov_insn_sz : 0;
HOST_WIDE_INT offset_adjust;
the insns must have the appropriate alternatives. */
if ((mode == QImode || mode == HImode) && rclass != R0_REGS
&& satisfies_constraint_Sdd (x)
- && disp_addr_displacement (x) <= max_mov_insn_displacement (mode, false))
+ && sh_disp_addr_displacement (x)
+ <= sh_max_mov_insn_displacement (mode, false))
return R0_REGS;
/* When reload is trying to address a QImode or HImode subreg on the stack,
(define_peephole2
[(set (match_operand:SI 0 "arith_reg_dest" "")
(zero_extend:SI (match_operand 1 "displacement_mem_operand" "")))
- (set (match_operand 2 "general_operand" "")
+ (set (match_operand 2 "nonimmediate_operand" "")
(match_operand 3 "arith_reg_operand" ""))]
"TARGET_SH2A
&& REGNO (operands[0]) == REGNO (operands[3])
prepare_move_operands (operands, QImode);
})
-;; If movqi_reg_reg is specified as an alternative of movqi, movqi will be
-;; selected to copy QImode regs. If one of them happens to be allocated
-;; on the stack, reload will stick to movqi insn and generate wrong
-;; displacement addressing because of the generic m alternatives.
-;; With the movqi_reg_reg being specified before movqi it will be initially
-;; picked to load/store regs. If the regs regs are on the stack reload
-;; try other insns and not stick to movqi_reg_reg, unless there were spilled
-;; pseudos in which case 'm' constraints pertain.
-;; The same applies to the movhi variants.
-;;
-;; Notice, that T bit is not allowed as a mov src operand here. This is to
-;; avoid things like (set (reg:QI) (subreg:QI (reg:SI T_REG) 0)), which
-;; introduces zero extensions after T bit stores and redundant reg copies.
-;;
-;; FIXME: We can't use 'arith_reg_operand' (which disallows T_REG) as a
-;; predicate for the mov src operand because reload will have trouble
-;; reloading MAC subregs otherwise. For that probably special patterns
-;; would be required.
-(define_insn "*mov<mode>_reg_reg"
- [(set (match_operand:QIHI 0 "arith_reg_dest" "=r,m,*z")
- (match_operand:QIHI 1 "register_operand" "r,*z,m"))]
- "TARGET_SH1 && !t_reg_operand (operands[1], VOIDmode)"
- "@
- mov %1,%0
- mov.<bw> %1,%0
- mov.<bw> %1,%0"
- [(set_attr "type" "move,store,load")])
-
+;; Specifying the displacement addressing load / store patterns separately
+;; before the generic movqi / movhi pattern allows controlling the order
+;; in which load / store insns are selected in a more fine grained way.
;; FIXME: The non-SH2A and SH2A variants should be combined by adding
;; "enabled" attribute as it is done in other targets.
(define_insn "*mov<mode>_store_mem_disp04"
[(set_attr "type" "load")
(set_attr "length" "2,2,4")])
-;; The m constraints basically allow any kind of addresses to be used with any
-;; source/target register as the other operand. This is not true for
-;; displacement addressing modes on anything but SH2A. That's why the
-;; specialized load/store insns are specified above.
-(define_insn "*movqi"
- [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,l")
- (match_operand:QI 1 "general_movsrc_operand" "i,m,r,l,r"))]
+;; The order of the constraint alternatives is important here.
+;; Q/r has to come first, otherwise PC relative loads might wrongly get
+;; placed into delay slots. Since there is no QImode PC relative load, the
+;; Q constraint and general_movsrc_operand will reject it for QImode.
+;; The Snd alternatives should come before Sdd in order to avoid a preference
+;; of using r0 als the register operand for addressing modes other than
+;; displacement addressing.
+;; The Sdd alternatives allow only r0 as register operand, even though on
+;; SH2A any register could be allowed by switching to a 32 bit insn.
+;; Generally sticking to the r0 is preferrable, since it generates smaller
+;; code. Obvious r0 reloads can then be eliminated with a peephole on SH2A.
+(define_insn "*mov<mode>"
+ [(set (match_operand:QIHI 0 "general_movdst_operand"
+ "=r,r,r,Snd,r, Sdd,z, r,l")
+ (match_operand:QIHI 1 "general_movsrc_operand"
+ "Q,r,i,r, Snd,z, Sdd,l,r"))]
"TARGET_SH1
- && (arith_reg_operand (operands[0], QImode)
- || arith_reg_operand (operands[1], QImode))"
+ && (arith_reg_operand (operands[0], <MODE>mode)
+ || arith_reg_operand (operands[1], <MODE>mode))"
"@
+ mov.<bw> %1,%0
mov %1,%0
- mov.b %1,%0
- mov.b %1,%0
- sts %1,%0
- lds %1,%0"
- [(set_attr "type" "movi8,load,store,prget,prset")])
-
-(define_insn "*movhi"
- [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,m,r,l")
- (match_operand:HI 1 "general_movsrc_operand" "Q,i,m,r,l,r"))]
- "TARGET_SH1
- && (arith_reg_operand (operands[0], HImode)
- || arith_reg_operand (operands[1], HImode))"
- "@
- mov.w %1,%0
mov %1,%0
- mov.w %1,%0
- mov.w %1,%0
+ mov.<bw> %1,%0
+ mov.<bw> %1,%0
+ mov.<bw> %1,%0
+ mov.<bw> %1,%0
sts %1,%0
lds %1,%0"
- [(set_attr "type" "pcload,movi8,load,store,prget,prset")])
+ [(set_attr "type" "pcload,move,movi8,store,load,store,load,prget,prset")
+ (set (attr "length")
+ (cond [(and (match_operand 0 "displacement_mem_operand")
+ (not (match_operand 0 "short_displacement_mem_operand")))
+ (const_int 4)
+ (and (match_operand 1 "displacement_mem_operand")
+ (not (match_operand 1 "short_displacement_mem_operand")))
+ (const_int 4)]
+ (const_int 2)))])
(define_insn "*movqi_media"
[(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
(label_ref (match_operand 1 "" ""))
(pc)))
(set (match_operand:SI 0 "arith_reg_dest" "=r")
- (plus (match_dup 2) (const_int -1)))
+ (plus:SI (match_dup 2) (const_int -1)))
(clobber (reg:SI T_REG))]
"TARGET_SH2"
"#"
;; -------------------------------------------------------------------------
;; This matches cases where the bit in a memory location is set.
(define_peephole2
- [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
- (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
+ [(set (match_operand:SI 0 "register_operand")
+ (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand")))
(set (match_dup 0)
(ior:SI (match_dup 0)
- (match_operand:SI 2 "const_int_operand" "Pso,Pso")))
+ (match_operand:SI 2 "const_int_operand")))
(set (match_dup 1)
- (match_operand 3 "arith_reg_operand" "r,r"))]
+ (match_operand 3 "arith_reg_operand"))]
"TARGET_SH2A && TARGET_BITOPS
&& satisfies_constraint_Pso (operands[2])
&& REGNO (operands[0]) == REGNO (operands[3])"
;; This matches cases where the bit in a memory location is cleared.
(define_peephole2
- [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
- (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
+ [(set (match_operand:SI 0 "register_operand")
+ (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand")))
(set (match_dup 0)
(and:SI (match_dup 0)
- (match_operand:SI 2 "const_int_operand" "Psz,Psz")))
+ (match_operand:SI 2 "const_int_operand")))
(set (match_dup 1)
- (match_operand 3 "arith_reg_operand" "r,r"))]
+ (match_operand 3 "arith_reg_operand"))]
"TARGET_SH2A && TARGET_BITOPS
&& satisfies_constraint_Psz (operands[2])
&& REGNO (operands[0]) == REGNO (operands[3])"
#include "target.h"
#include <vector>
+#include <algorithm>
/*
This pass tries to eliminate unnecessary sett or clrt instructions in cases
struct ccreg_value
{
// The insn at which the ccreg value was determined.
+ // Might be NULL_RTX if e.g. an unknown value is recorded for an
+ // empty basic block.
rtx insn;
// The basic block where the insn was discovered.
- // Notice that the CFG might be invalid at late RTL stages and
- // BLOCK_FOR_INSN might return null. Thus the basic block are recorded
- // here while traversing them.
basic_block bb;
- // The value of ccreg. If NULL_RTX, the value is not known, e.g. if the
- // ccreg is clobbered.
+ // The value of ccreg. If NULL_RTX, the exact value is not known, but
+ // the ccreg is changed in some way (e.g. clobbered).
rtx value;
};
// start insn.
void find_last_ccreg_values (rtx start_insn, basic_block bb,
std::vector<ccreg_value>& values_out,
- basic_block prev_visited_bb = NULL) const;
+ std::vector<basic_block>& prev_visited_bb) const;
// Given a cbranch insn, its basic block and another basic block, determine
// the value to which the ccreg will be set after jumping/falling through to
std::vector<ccreg_value> ccreg_values;
ccreg_values.reserve (32);
+ // Something for recording visited basic blocks to avoid infinite recursion.
+ std::vector<basic_block> visited_bbs;
+ visited_bbs.reserve (32);
+
// Look for insns that set the ccreg to a constant value and see if it can
// be optimized.
basic_block bb;
log_msg ("\n");
ccreg_values.clear ();
- find_last_ccreg_values (PREV_INSN (i), bb, ccreg_values);
+ visited_bbs.clear ();
+ find_last_ccreg_values (PREV_INSN (i), bb, ccreg_values,
+ visited_bbs);
log_msg ("number of ccreg values collected: %u\n",
(unsigned int)ccreg_values.size ());
sh_optimize_sett_clrt
::find_last_ccreg_values (rtx start_insn, basic_block bb,
std::vector<ccreg_value>& values_out,
- basic_block prev_visited_bb) const
+ std::vector<basic_block>& prev_visited_bb) const
{
- if (start_insn == NULL_RTX)
- return;
-
- log_msg ("looking for ccreg values in [bb %d]\n", bb->index);
+ // FIXME: For larger CFGs this will unnecessarily re-visit basic blocks.
+ // Once a basic block has been visited, the result should be stored in
+ // some container so that it can be looked up quickly eliminating the
+ // re-visits.
+ log_msg ("looking for ccreg values in [bb %d] ", bb->index);
+ if (!prev_visited_bb.empty ())
+ log_msg ("(prev visited [bb %d])", prev_visited_bb.back ()->index);
+ log_msg ("\n");
for (rtx i = start_insn; i != NULL_RTX && i != PREV_INSN (BB_HEAD (bb));
i = PREV_INSN (i))
return;
}
- if (any_condjump_p (i) && onlyjump_p (i) && prev_visited_bb != NULL)
+ if (any_condjump_p (i) && onlyjump_p (i) && !prev_visited_bb.empty ())
{
// For a conditional branch the ccreg value will be a known constant
// of either 0 or STORE_FLAG_VALUE after branching/falling through
ccreg_value v;
v.insn = i;
v.bb = bb;
- v.value = GEN_INT (sh_cbranch_ccreg_value (i, bb, prev_visited_bb));
+ v.value = GEN_INT (sh_cbranch_ccreg_value (i, bb,
+ prev_visited_bb.back ()));
log_msg (" branches to [bb %d] with ccreg value ",
- prev_visited_bb->index);
+ prev_visited_bb.back ()->index);
log_rtx (v.value);
log_msg ("\n");
// In this case, check the predecessor basic blocks.
unsigned int pred_bb_count = 0;
- // If the current basic block is the same as the previous one, it's a loop.
- // Don't try to recurse again, as this will result in an infinite loop.
- if (bb != prev_visited_bb)
- for (edge_iterator ei = ei_start (bb->preds); !ei_end_p (ei); ei_next (&ei))
- {
- basic_block pred_bb = ei_edge (ei)->src;
- if (pred_bb->index == ENTRY_BLOCK)
- continue;
+ // If the current basic block is not in the stack of previously visited
+ // basic blocks yet, we can recursively check the predecessor basic blocks.
+ // Otherwise we have a loop in the CFG and recursing again will result in
+ // an infinite loop.
+ if (std::find (prev_visited_bb.rbegin (), prev_visited_bb.rend (), bb)
+ == prev_visited_bb.rend ())
+ {
+ prev_visited_bb.push_back (bb);
- pred_bb_count += 1;
- find_last_ccreg_values (BB_END (pred_bb), pred_bb, values_out, bb);
- }
+ for (edge_iterator ei = ei_start (bb->preds); !ei_end_p (ei);
+ ei_next (&ei))
+ {
+ basic_block pred_bb = ei_edge (ei)->src;
+ pred_bb_count += 1;
+ find_last_ccreg_values (BB_END (pred_bb), pred_bb, values_out,
+ prev_visited_bb);
+ }
+
+ prev_visited_bb.pop_back ();
+ }
+ else
+ log_msg ("loop detected for [bb %d]\n", bb->index);
log_msg ("[bb %d] pred_bb_count = %u\n", bb->index, pred_bb_count);
- // If here, we've walked up all the predecessor basic blocks without finding
- // anything setcc related. Add an entry for the last insn of the current
- // basic block with the ccreg value being set to unknown (NULL_RTX).
if (pred_bb_count == 0)
{
+ // If we haven't checked a single predecessor basic block, the current
+ // basic block is probably a leaf block and we don't know the ccreg value.
log_msg ("unknown ccreg value for [bb %d]\n", bb->index);
ccreg_value v;
#undef LINK_ARCH_SPEC
#define LINK_ARCH_SPEC LINK_ARCH32_SPEC
+/* C++11 programs need -lrt for nanosleep. */
+#define TIME_LIBRARY "rt"
+
#ifndef USE_GLD
/* With Sun ld, -rdynamic is a no-op. */
#define RDYNAMIC_SPEC ""
#include "target.h"
#include "target-def.h"
#include "common/common-target.h"
+#include "pointer-set.h"
+#include "hash-table.h"
+#include "vec.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-fold.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimplify.h"
#include "langhooks.h"
#include "sched-int.h"
#include "params.h"
#include "machmode.h"
+#include "pointer-set.h"
+#include "hash-table.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-fold.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimplify.h"
#include "tm-constrs.h"
#include "target-def.h"
#include "tm_p.h"
#include "langhooks.h"
+#include "pointer-set.h"
+#include "hash-table.h"
+#include "vec.h"
+#include "ggc.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-fold.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimplify.h"
#include "df.h"
#include "reload.h"
-#include "ggc.h"
static rtx emit_addhi3_postreload (rtx, rtx, rtx);
static void xstormy16_asm_out_constructor (rtx, int);
#include "dwarf2.h"
#include "timevar.h"
#include "tree.h"
+#include "pointer-set.h"
+#include "hash-table.h"
+#include "vec.h"
+#include "ggc.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-fold.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "stringpool.h"
#include "stor-layout.h"
#include "dwarf2.h"
#include "timevar.h"
#include "tree.h"
+#include "pointer-set.h"
+#include "hash-table.h"
+#include "vec.h"
+#include "ggc.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-fold.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "stringpool.h"
#include "stor-layout.h"
#include "target.h"
#include "target-def.h"
#include "langhooks.h"
+#include "pointer-set.h"
+#include "hash-table.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-fold.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimplify.h"
#include "df.h"
gcc_cv_objdump
ORIGINAL_NM_FOR_TARGET
gcc_cv_nm
+ORIGINAL_LD_GOLD_FOR_TARGET
+ORIGINAL_LD_BFD_FOR_TARGET
ORIGINAL_LD_FOR_TARGET
ORIGINAL_PLUGIN_LD_FOR_TARGET
gcc_cv_ld
with_pic
enable_fast_install
enable_libtool_lock
+enable_ld
+enable_gold
with_plugin_ld
enable_gnu_indirect_function
enable_initfini_array
--enable-fast-install[=PKGS]
optimize for fast installation [default=yes]
--disable-libtool-lock avoid locking (might break parallel builds)
+ --enable-ld[=ARG] build ld [ARG={default,yes,no}]
+ --enable-gold[=ARG] build gold [ARG={default,yes,no}]
--enable-gnu-indirect-function
enable the use of the @gnu_indirect_function to
glibc systems
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 17916 "configure"
+#line 17922 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 18022 "configure"
+#line 18028 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
in_tree_gas=no
fi
+default_ld=
+# Check whether --enable-ld was given.
+if test "${enable_ld+set}" = set; then :
+ enableval=$enable_ld; case "${enableval}" in
+ no)
+ default_ld=ld.gold
+ ;;
+ esac
+fi
+
+
+# Check whether --enable-gold was given.
+if test "${enable_gold+set}" = set; then :
+ enableval=$enable_gold; case "${enableval}" in
+ default)
+ install_gold_as_default=yes
+ ;;
+ yes)
+ if test x${default_ld} != x; then
+ install_gold_as_default=yes
+ fi
+ ;;
+ no)
+ ;;
+ *)
+ as_fn_error "invalid --enable-gold argument" "$LINENO" 5
+ ;;
+ esac
+else
+ install_gold_as_default=no
+fi
+
+
# Identify the linker which will work hand-in-glove with the newly
# built GCC, so that we can examine its features. This is the linker
# which will be driven by the driver program.
gcc_cv_gld_major_version=
gcc_cv_gld_minor_version=
gcc_cv_ld_gld_srcdir=`echo $srcdir | sed -e 's,/gcc$,,'`/ld
+gcc_cv_ld_gold_srcdir=`echo $srcdir | sed -e 's,/gcc$,,'`/gold
gcc_cv_ld_bfd_srcdir=`echo $srcdir | sed -e 's,/gcc$,,'`/bfd
if test "${gcc_cv_ld+set}" = set; then :
if test -x "$DEFAULT_LINKER"; then
gcc_cv_ld="$DEFAULT_LINKER"
+elif test $install_gold_as_default = yes \
+ && test -f $gcc_cv_ld_gold_srcdir/configure.ac \
+ && test -f ../gold/Makefile \
+ && test x$build = x$host; then
+ gcc_cv_ld=../gold/ld-new$build_exeext
elif test -f $gcc_cv_ld_gld_srcdir/configure.in \
&& test -f ../ld/Makefile \
&& test x$build = x$host; then
esac
gcc_cv_gld_major_version=`expr "$gcc_cv_gld_version" : "VERSION=\([0-9]*\)"`
gcc_cv_gld_minor_version=`expr "$gcc_cv_gld_version" : "VERSION=[0-9]*\.\([0-9]*\)"`
+ ORIGINAL_LD_BFD_FOR_TARGET=../ld/ld-new$build_exeext
+ ORIGINAL_LD_GOLD_FOR_TARGET=../gold/ld-new$build_exeext
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_ld" >&5
$as_echo "$gcc_cv_ld" >&6; }
in_tree_ld=no
+ gcc_cvs_ld_program=`dirname $gcc_cv_ld`/`basename $gcc_cv_ld $host_exeext`
+ ORIGINAL_LD_BFD_FOR_TARGET=${gcc_cvs_ld_program}.bfd$host_exeext
+ ORIGINAL_LD_GOLD_FOR_TARGET=${gcc_cvs_ld_program}.gold$host_exeext
fi
+
+
+
# Figure out what nm we will be using.
gcc_cv_binutils_srcdir=`echo $srcdir | sed -e 's,/gcc$,,'`/binutils
if test "${gcc_cv_nm+set}" = set; then :
in_tree_gas=no
fi
+default_ld=
+AC_ARG_ENABLE(ld,
+[[ --enable-ld[=ARG] build ld [ARG={default,yes,no}]]],
+[case "${enableval}" in
+ no)
+ default_ld=ld.gold
+ ;;
+ esac])
+
+AC_ARG_ENABLE(gold,
+[[ --enable-gold[=ARG] build gold [ARG={default,yes,no}]]],
+[case "${enableval}" in
+ default)
+ install_gold_as_default=yes
+ ;;
+ yes)
+ if test x${default_ld} != x; then
+ install_gold_as_default=yes
+ fi
+ ;;
+ no)
+ ;;
+ *)
+ AC_MSG_ERROR([invalid --enable-gold argument])
+ ;;
+ esac],
+[install_gold_as_default=no])
+
# Identify the linker which will work hand-in-glove with the newly
# built GCC, so that we can examine its features. This is the linker
# which will be driven by the driver program.
gcc_cv_gld_major_version=
gcc_cv_gld_minor_version=
gcc_cv_ld_gld_srcdir=`echo $srcdir | sed -e 's,/gcc$,,'`/ld
+gcc_cv_ld_gold_srcdir=`echo $srcdir | sed -e 's,/gcc$,,'`/gold
gcc_cv_ld_bfd_srcdir=`echo $srcdir | sed -e 's,/gcc$,,'`/bfd
AS_VAR_SET_IF(gcc_cv_ld,, [
if test -x "$DEFAULT_LINKER"; then
gcc_cv_ld="$DEFAULT_LINKER"
+elif test $install_gold_as_default = yes \
+ && test -f $gcc_cv_ld_gold_srcdir/configure.ac \
+ && test -f ../gold/Makefile \
+ && test x$build = x$host; then
+ gcc_cv_ld=../gold/ld-new$build_exeext
elif test -f $gcc_cv_ld_gld_srcdir/configure.in \
&& test -f ../ld/Makefile \
&& test x$build = x$host; then
gcc_cv_gld_major_version=`expr "$gcc_cv_gld_version" : "VERSION=\([0-9]*\)"`
gcc_cv_gld_minor_version=`expr "$gcc_cv_gld_version" : "VERSION=[0-9]*\.\([0-9]*\)"`
changequote([,])dnl
+ ORIGINAL_LD_BFD_FOR_TARGET=../ld/ld-new$build_exeext
+ ORIGINAL_LD_GOLD_FOR_TARGET=../gold/ld-new$build_exeext
else
AC_MSG_RESULT($gcc_cv_ld)
in_tree_ld=no
+ gcc_cvs_ld_program=`dirname $gcc_cv_ld`/`basename $gcc_cv_ld $host_exeext`
+ ORIGINAL_LD_BFD_FOR_TARGET=${gcc_cvs_ld_program}.bfd$host_exeext
+ ORIGINAL_LD_GOLD_FOR_TARGET=${gcc_cvs_ld_program}.gold$host_exeext
fi
+AC_SUBST(ORIGINAL_LD_BFD_FOR_TARGET)
+AC_SUBST(ORIGINAL_LD_GOLD_FOR_TARGET)
+
# Figure out what nm we will be using.
gcc_cv_binutils_srcdir=`echo $srcdir | sed -e 's,/gcc$,,'`/binutils
AS_VAR_SET_IF(gcc_cv_nm,, [
+2013-11-29 Marek Polacek <polacek@redhat.com>
+
+ PR sanitizer/59331
+ * decl.c (compute_array_index_type): Don't build COMPOUND_EXPR for
+ instrumentation.
+
+2013-11-28 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/59297
+ * semantics.c (finish_omp_atomic): Call finish_expr_stmt
+ rather than add_stmt.
+
+2013-11-28 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ * g++spec.c (TIMELIB): Define.
+ (WITHLIBC, SKIPOPT): Adjust values.
+ (lang_specific_driver): Add TIME_LIBRARY if not passed explicitly.
+
+2013-11-28 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/59310
+ * parser.c (cp_parser_omp_target): Call keep_next_level only
+ if flag_openmp.
+
+2013-11-27 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58647
+ * semantics.c (cxx_eval_constant_expression, [COMPONENT_REF]):
+ Handle function COMPONENT_REFs.
+
+2013-11-27 Aldy Hernandez <aldyh@redhat.com>
+ Jakub Jelinek <jakub@redhat.com>
+
+ * semantics.c (finish_omp_clauses): For #pragma omp declare simd
+ linear clause step call maybe_constant_value.
+
+2013-11-27 Tom de Vries <tom@codesourcery.com>
+ Marc Glisse <marc.glisse@inria.fr>
+
+ PR c++/59032
+ * typeck.c (cp_build_unary_op): Allow vector increment and decrement.
+
+2013-11-27 Tom de Vries <tom@codesourcery.com>
+ Marc Glisse <marc.glisse@inria.fr>
+
+ PR middle-end/59037
+ * semantics.c (cxx_fold_indirect_ref): Don't create out-of-bounds
+ BIT_FIELD_REF.
+
+2013-11-26 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/58874
+ * parser.c (cp_parser_late_parsing_for_member): For OpenMP UDRs
+ pass 2 instead of 0 to finish_function.
+
+2013-11-26 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58700
+ * decl.c (grokdeclarator): Don't try to pass declarator->id_loc
+ to build_lang_decl_loc when declarator is null.
+
+2013-11-26 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * cvt.c (cp_convert_and_check): Avoid calling cp_convert
+ unnecessarily.
+
+2013-11-25 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/54485
+ * decl.c (duplicate_decls): Enforce 8.3.6/6 about default arguments
+ for member functions of class templates.
+
+2013-11-25 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58607
+ * semantics.c (check_constexpr_ctor_body): Check for BIND_EXPR_VARS.
+
+2013-11-25 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58810
+ * decl.c (grokdeclarator): Don't handle qualified free functions here,
+ leave the diagnostic to grokfndecl.
+
+2013-11-25 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/59080
+ * pt.c (unify): Don't call unify_array_domain with a NULL_TREE
+ third argument.
+
+ PR c++/59096
+ * pt.c (apply_late_template_attributes): Check that TREE_VALUE
+ isn't NULL_TREE in the attribute_takes_identifier_p case.
+
+2013-11-25 Adam Butcher <adam@jessamine.co.uk>
+
+ PR c++/59112
+ PR c++/59113
+ * parser.c (cp_parser_parameter_declaration_clause): Disallow implicit
+ function templates in local functions unless defining a lambda.
+
+2013-11-23 Easwaran Raman <eraman@google.com>
+
+ PR c++/59031
+ * call.c (build_new_method_call_1): Comnpare function context
+ with BASELINK_BINFO type rather than instance type before
+ marking the call with LOOKUP_NONVIRTUAL.
+
+2013-11-23 Jason Merrill <jason@redhat.com>
+
+ PR c++/58868
+ * init.c (build_aggr_init): Don't clobber the type of init
+ if we got an INIT_EXPR back from build_vec_init.
+ (build_vec_init): Do digest_init on trivial initialization.
+
+2013-11-23 Alexander Ivchenko <alexander.ivchenko@intel.com>
+
+ PR c++/58525
+ * call.c (build_operator_new_call): Add flag_exceptions check.
+ * decl.c (compute_array_index_type): Ditto.
+ * init.c (build_new_1): Ditto.
+ (build_vec_init): Ditto.
+
+2013-11-22 Jakub Jelinek <jakub@redhat.com>
+
+ * cp-gimplify.c: Include target.h and c-family/c-ubsan.h.
+ (cp_ubsan_maybe_instrument_return): New function.
+ (cp_genericize): Call it if -fsanitize=return.
+
+ * decl2.c: Include asan.h.
+ (one_static_initialization_or_destruction): If -fsanitize=address,
+ init is non-NULL and guard is NULL, set
+ vnode->dynamically_initialized.
+ (do_static_initialization_or_destruction): Call
+ __asan_{before,after}_dynamic_init around the static initialization.
+
+2013-11-22 Andrew MacLeod <amacleod@redhat.com>
+
+ * class.c: Add required include files from gimple.h.
+ * cp-gimplify.c: Likewise
+ * decl2.c: Likewise
+ * init.c: Likewise
+ * optimize.c: Likewise
+ * pt.c: Likewise
+ * semantics.c: Likewise
+ * tree.c: Likewise
+ * typeck.c: Likewise
+ * vtable-class-hierarchy.c: Likewise
+
+2013-11-22 David Malcolm <dmalcolm@redhat.com>
+
+ * call.c (build_integral_nontype_arg_conv): Remove use of
+ EXPR_LOC_OR_HERE macro.
+ (convert_like_real): Likewise.
+ (convert_arg_to_ellipsis): Likewise.
+ (build_cxx_call): Likewise.
+ (perform_implicit_conversion_flags): Likewise.
+ (initialize_reference): Likewise.
+ * cvt.c (cp_convert_to_pointer): Likewise.
+ (convert_to_reference): Likewise.
+ (ocp_convert): Likewise.
+ (convert_to_void): Likewise.
+ * decl.c (pop_label): Update comment.
+ (pop_switch): Remove use of EXPR_LOC_OR_HERE macro.
+ (check_tag_decl): Remove use of in_system_header macro.
+ (make_rtl_for_nonlocal_decl): Remove use of input_filename
+ macro.
+ (compute_array_index_type): Remove use of in_system_header
+ macro.
+ (grokdeclarator): Likewise.
+ * error.c (dump_global_iord): Remove use of input_filename
+ macro.
+ (location_of): Remove use of EXPR_LOC_OR_HERE macro.
+ (maybe_warn_cpp0x): Remove use of in_system_header macro.
+ * init.c (build_new_1): Remove use of EXPR_LOC_OR_HERE macro.
+ * lex.c (handle_pragma_interface): Remove use of input_filename
+ macro.
+ (handle_pragma_implementation): Likewise.
+ (cxx_make_type): Likewise.
+ (in_main_input_context): Likewise.
+ * name-lookup.c (push_binding_level): Remove use of
+ input_line macro.
+ (leave_scope): Likewise.
+ (resume_scope): Likewise.
+ * parser.c (cp_parser_unqualified_id): Remove use of
+ in_system_header macro.
+ (cp_parser_cast_expression): Likewise.
+ (cp_parser_declaration_seq_opt): Likewise.
+ (cp_parser_enumerator_list): Likewise.
+ (cp_parser_parameter_declaration_clause): Likewise.
+ (cp_parser_exception_specification_opt): Likewise.
+ * pt.c (unify_arg_conversion): Remove use of EXPR_LOC_OR_HERE
+ macro.
+ (convert_nontype_argument): Likewise.
+ (push_tinst_level): Remove use of in_system_header macro.
+ (tsubst_copy_and_build): Remove use of EXPR_LOC_OR_HERE
+ macros.
+ (do_decl_instantiation): Remove use of in_system_header macro.
+ (do_type_instantiation): Likewise.
+ * semantics.c (finish_call_expr): Remove use of EXPR_LOC_OR_HERE
+ macro.
+ (begin_class_definition): Remove use of input_filename macro.
+ (cxx_eval_call_expression): Remove use of EXPR_LOC_OR_HERE
+ macro.
+ (cxx_eval_constant_expression): Likewise.
+ (potential_constant_expression_1): Likewise.
+ * typeck.c (decay_conversion): Likewise.
+ (rationalize_conditional_expr): Likewise.
+ (build_x_compound_expr_from_list): Likewise.
+ (convert_for_assignment): Likewise.
+ * typeck2.c (check_narrowing): Likewise.
+
2013-11-22 Trevor Saunders <tsaunders@mozilla.com>
* parser.c, semantics.c: Change some local variables from vec to
conversion *conv;
void *p;
tree t;
- location_t loc = EXPR_LOC_OR_HERE (expr);
+ location_t loc = EXPR_LOC_OR_LOC (expr, input_location);
if (error_operand_p (expr))
return error_mark_node;
if (size_check != NULL_TREE)
{
tree errval = TYPE_MAX_VALUE (sizetype);
- if (cxx_dialect >= cxx11)
+ if (cxx_dialect >= cxx11 && flag_exceptions)
errval = throw_bad_array_new_length ();
*size = fold_build3 (COND_EXPR, sizetype, size_check,
original_size, errval);
tree totype = convs->type;
diagnostic_t diag_kind;
int flags;
- location_t loc = EXPR_LOC_OR_HERE (expr);
+ location_t loc = EXPR_LOC_OR_LOC (expr, input_location);
if (convs->bad_p && !(complain & tf_error))
return error_mark_node;
convert_arg_to_ellipsis (tree arg, tsubst_flags_t complain)
{
tree arg_type;
- location_t loc = EXPR_LOC_OR_HERE (arg);
+ location_t loc = EXPR_LOC_OR_LOC (arg, input_location);
/* [expr.call]
int optimize_sav;
/* Remember roughly where this call is. */
- location_t loc = EXPR_LOC_OR_HERE (fn);
+ location_t loc = EXPR_LOC_OR_LOC (fn, input_location);
fn = build_call_a (fn, nargs, argarray);
SET_EXPR_LOCATION (fn, loc);
struct z_candidate *candidates = 0, *cand;
tree explicit_targs = NULL_TREE;
tree basetype = NULL_TREE;
- tree access_binfo;
+ tree access_binfo, binfo;
tree optype;
tree first_mem_arg = NULL_TREE;
tree name;
if (!conversion_path)
conversion_path = BASELINK_BINFO (fns);
access_binfo = BASELINK_ACCESS_BINFO (fns);
+ binfo = BASELINK_BINFO (fns);
optype = BASELINK_OPTYPE (fns);
fns = BASELINK_FUNCTIONS (fns);
if (TREE_CODE (fns) == TEMPLATE_ID_EXPR)
{
/* Optimize away vtable lookup if we know that this
function can't be overridden. We need to check if
- the context and the instance type are the same,
+ the context and the type where we found fn are the same,
actually FN might be defined in a different class
type because of a using-declaration. In this case, we
do not want to perform a non-virtual call. */
if (DECL_VINDEX (fn) && ! (flags & LOOKUP_NONVIRTUAL)
&& same_type_ignoring_top_level_qualifiers_p
- (DECL_CONTEXT (fn), TREE_TYPE (instance))
+ (DECL_CONTEXT (fn), BINFO_TYPE (binfo))
&& resolves_to_fixed_type_p (instance, 0))
flags |= LOOKUP_NONVIRTUAL;
if (explicit_targs)
{
conversion *conv;
void *p;
- location_t loc = EXPR_LOC_OR_HERE (expr);
+ location_t loc = EXPR_LOC_OR_LOC (expr, input_location);
if (error_operand_p (expr))
return error_mark_node;
{
conversion *conv;
void *p;
- location_t loc = EXPR_LOC_OR_HERE (expr);
+ location_t loc = EXPR_LOC_OR_LOC (expr, input_location);
if (type == error_mark_node || error_operand_p (expr))
return error_mark_node;
#include "stringpool.h"
#include "stor-layout.h"
#include "attribs.h"
-#include "gimple.h"
+#include "pointer-set.h"
+#include "hash-table.h"
#include "cp-tree.h"
#include "flags.h"
#include "toplev.h"
#include "cgraph.h"
#include "dumpfile.h"
#include "splay-tree.h"
-#include "pointer-set.h"
-#include "hash-table.h"
-#include "gimple.h"
#include "gimplify.h"
#include "wide-int.h"
#include "cp-tree.h"
#include "c-family/c-common.h"
#include "tree-iterator.h"
+#include "pointer-set.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimplify.h"
#include "hashtab.h"
-#include "pointer-set.h"
#include "flags.h"
#include "splay-tree.h"
+#include "target.h"
+#include "c-family/c-ubsan.h"
/* Forward declarations. */
wtd.bind_expr_stack.release ();
}
+/* If a function that should end with a return in non-void
+ function doesn't obviously end with return, add ubsan
+ instrmentation code to verify it at runtime. */
+
+static void
+cp_ubsan_maybe_instrument_return (tree fndecl)
+{
+ if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fndecl)))
+ || DECL_CONSTRUCTOR_P (fndecl)
+ || DECL_DESTRUCTOR_P (fndecl)
+ || !targetm.warn_func_return (fndecl))
+ return;
+
+ tree t = DECL_SAVED_TREE (fndecl);
+ while (t)
+ {
+ switch (TREE_CODE (t))
+ {
+ case BIND_EXPR:
+ t = BIND_EXPR_BODY (t);
+ continue;
+ case TRY_FINALLY_EXPR:
+ t = TREE_OPERAND (t, 0);
+ continue;
+ case STATEMENT_LIST:
+ {
+ tree_stmt_iterator i = tsi_last (t);
+ if (!tsi_end_p (i))
+ {
+ t = tsi_stmt (i);
+ continue;
+ }
+ }
+ break;
+ case RETURN_EXPR:
+ return;
+ default:
+ break;
+ }
+ break;
+ }
+ if (t == NULL_TREE)
+ return;
+ t = DECL_SAVED_TREE (fndecl);
+ if (TREE_CODE (t) == BIND_EXPR
+ && TREE_CODE (BIND_EXPR_BODY (t)) == STATEMENT_LIST)
+ {
+ tree_stmt_iterator i = tsi_last (BIND_EXPR_BODY (t));
+ t = ubsan_instrument_return (DECL_SOURCE_LOCATION (fndecl));
+ tsi_link_after (&i, t, TSI_NEW_STMT);
+ }
+}
+
void
cp_genericize (tree fndecl)
{
walk_tree's hash functionality. */
cp_genericize_tree (&DECL_SAVED_TREE (fndecl));
+ if (flag_sanitize & SANITIZE_RETURN)
+ cp_ubsan_maybe_instrument_return (fndecl);
+
/* Do everything else. */
c_genericize (fndecl);
/* Returns true iff NODE is a BASELINK. */
#define BASELINK_P(NODE) \
(TREE_CODE (NODE) == BASELINK)
-/* The BINFO indicating the base from which the BASELINK_FUNCTIONS came. */
+/* The BINFO indicating the base in which lookup found the
+ BASELINK_FUNCTIONS. */
#define BASELINK_BINFO(NODE) \
(((struct tree_baselink*) BASELINK_CHECK (NODE))->binfo)
/* The functions referred to by the BASELINK; either a FUNCTION_DECL,
tree intype = TREE_TYPE (expr);
enum tree_code form;
tree rval;
- location_t loc = EXPR_LOC_OR_HERE (expr);
+ location_t loc = EXPR_LOC_OR_LOC (expr, input_location);
if (intype == error_mark_node)
return error_mark_node;
tree rval = NULL_TREE;
tree rval_as_conversion = NULL_TREE;
bool can_convert_intype_to_type;
- location_t loc = EXPR_LOC_OR_HERE (expr);
+ location_t loc = EXPR_LOC_OR_LOC (expr, input_location);
if (TREE_CODE (type) == FUNCTION_TYPE
&& TREE_TYPE (expr) == unknown_type_node)
{
tree folded = maybe_constant_value (expr);
tree stripped = folded;
- tree folded_result = cp_convert (type, folded, complain);
+ tree folded_result
+ = folded != expr ? cp_convert (type, folded, complain) : result;
/* maybe_constant_value wraps an INTEGER_CST with TREE_OVERFLOW in a
NOP_EXPR so that it isn't TREE_CONSTANT anymore. */
enum tree_code code = TREE_CODE (type);
const char *invalid_conv_diag;
tree e1;
- location_t loc = EXPR_LOC_OR_HERE (expr);
+ location_t loc = EXPR_LOC_OR_LOC (expr, input_location);
if (error_operand_p (e) || type == error_mark_node)
return error_mark_node;
tree
convert_to_void (tree expr, impl_conv_void implicit, tsubst_flags_t complain)
{
- location_t loc = EXPR_LOC_OR_HERE (expr);
+ location_t loc = EXPR_LOC_OR_LOC (expr, input_location);
if (expr == error_mark_node
|| TREE_TYPE (expr) == error_mark_node)
location_t location;
error ("label %q+D used but not defined", label);
- location = input_location; /* FIXME want (input_filename, (line)0) */
+ location = input_location;
+ /* FIXME want (LOCATION_FILE (input_location), (line)0) */
/* Avoid crashing later. */
define_label (location, DECL_NAME (label));
}
if (TREE_CODE (TREE_TYPE (newdecl)) == METHOD_TYPE)
t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2);
- for (; t1 && t1 != void_list_node;
- t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2), i++)
- if (TREE_PURPOSE (t1) && TREE_PURPOSE (t2))
- {
- if (1 == simple_cst_equal (TREE_PURPOSE (t1),
- TREE_PURPOSE (t2)))
+ if (TREE_CODE (TREE_TYPE (newdecl)) == METHOD_TYPE
+ && CLASSTYPE_TEMPLATE_INFO (CP_DECL_CONTEXT (newdecl)))
+ {
+ /* C++11 8.3.6/6.
+ Default arguments for a member function of a class template
+ shall be specified on the initial declaration of the member
+ function within the class template. */
+ for (; t2 && t2 != void_list_node; t2 = TREE_CHAIN (t2))
+ if (TREE_PURPOSE (t2))
{
- permerror (input_location, "default argument given for parameter %d of %q#D",
- i, newdecl);
- permerror (input_location, "after previous specification in %q+#D", olddecl);
+ permerror (input_location,
+ "redeclaration of %q#D may not have default "
+ "arguments", newdecl);
+ break;
}
- else
+ }
+ else
+ {
+ for (; t1 && t1 != void_list_node;
+ t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2), i++)
+ if (TREE_PURPOSE (t1) && TREE_PURPOSE (t2))
{
- error ("default argument given for parameter %d of %q#D",
- i, newdecl);
- error ("after previous specification in %q+#D",
- olddecl);
+ if (1 == simple_cst_equal (TREE_PURPOSE (t1),
+ TREE_PURPOSE (t2)))
+ {
+ permerror (input_location,
+ "default argument given for parameter %d "
+ "of %q#D", i, newdecl);
+ permerror (input_location,
+ "after previous specification in %q+#D",
+ olddecl);
+ }
+ else
+ {
+ error ("default argument given for parameter %d "
+ "of %q#D", i, newdecl);
+ error ("after previous specification in %q+#D",
+ olddecl);
+ }
}
- }
+ }
}
}
location_t switch_location;
/* Emit warnings as needed. */
- switch_location = EXPR_LOC_OR_HERE (cs->switch_stmt);
+ switch_location = EXPR_LOC_OR_LOC (cs->switch_stmt, input_location);
if (!processing_template_decl)
c_do_switch_warnings (cs->cases, switch_location,
SWITCH_STMT_TYPE (cs->switch_stmt),
error ("multiple types in one declaration");
else if (declspecs->redefined_builtin_type)
{
- if (!in_system_header)
+ if (!in_system_header_at (input_location))
permerror (declspecs->locations[ds_redefined_builtin_type_spec],
"redeclaration of C++ built-in type %qT",
declspecs->redefined_builtin_type);
/* Anonymous unions are objects, so they can have specifiers. */;
SET_ANON_AGGR_TYPE_P (declared_type);
- if (TREE_CODE (declared_type) != UNION_TYPE && !in_system_header)
+ if (TREE_CODE (declared_type) != UNION_TYPE
+ && !in_system_header_at (input_location))
pedwarn (input_location, OPT_Wpedantic, "ISO C++ prohibits anonymous structs");
}
/* We try to defer namespace-scope static constants so that they are
not emitted into the object file unnecessarily. */
- filename = input_filename;
+ filename = LOCATION_FILE (input_location);
if (!DECL_VIRTUAL_P (decl)
&& TREE_READONLY (decl)
&& DECL_INITIAL (decl) != NULL_TREE
indicated by the state of complain), so that
another substitution can be found. */
return error_mark_node;
- else if (in_system_header)
+ else if (in_system_header_at (input_location))
/* Allow them in system headers because glibc uses them. */;
else if (name)
pedwarn (input_location, OPT_Wpedantic, "ISO C++ forbids zero-size array %qD", name);
stabilize_vla_size (itype);
- if (cxx_dialect >= cxx1y)
+ if (cxx_dialect >= cxx1y && flag_exceptions)
{
/* If the VLA bound is larger than half the address space,
or less than zero, throw std::bad_array_length. */
LE_EXPR rather than LT_EXPR. */
tree t = fold_build2 (PLUS_EXPR, TREE_TYPE (itype), itype,
build_one_cst (TREE_TYPE (itype)));
- t = fold_build2 (COMPOUND_EXPR, TREE_TYPE (t),
- ubsan_instrument_vla (input_location, t), t);
+ t = ubsan_instrument_vla (input_location, t);
finish_expr_stmt (t);
}
}
if (type_was_error_mark_node)
/* We've already issued an error, don't complain more. */;
- else if (in_system_header || flag_ms_extensions)
+ else if (in_system_header_at (input_location) || flag_ms_extensions)
/* Allow it, sigh. */;
else if (! is_main)
permerror (input_location, "ISO C++ forbids declaration of %qs with no type", name);
error ("%<__int128%> is not supported by this target");
explicit_int128 = false;
}
- else if (pedantic && ! in_system_header)
+ else if (pedantic && ! in_system_header_at (input_location))
pedwarn (input_location, OPT_Wpedantic,
"ISO C++ does not support %<__int128%> for %qs", name);
}
if (decl_context != TYPENAME)
{
- /* A cv-qualifier-seq shall only be part of the function type
- for a non-static member function. A ref-qualifier shall only
- .... /same as above/ [dcl.fct] */
- if ((type_memfn_quals (type) != TYPE_UNQUALIFIED
- || type_memfn_rqual (type) != REF_QUAL_NONE)
- && (current_class_type == NULL_TREE || staticp) )
- {
- error (staticp
- ? G_("qualified function types cannot be used to "
- "declare static member functions")
- : G_("qualified function types cannot be used to "
- "declare free functions"));
- type = TYPE_MAIN_VARIANT (type);
- }
-
/* The qualifiers on the function type become the qualifiers on
the non-static member function. */
memfn_quals |= type_memfn_quals (type);
{
/* C++ allows static class members. All other work
for this is done by grokfield. */
- decl = build_lang_decl_loc (declarator->id_loc,
+ decl = build_lang_decl_loc (declarator
+ ? declarator->id_loc
+ : input_location,
VAR_DECL, unqualified_id, type);
set_linkage_for_static_data_member (decl);
/* Even if there is an in-class initialization, DECL
#include "attribs.h"
#include "stor-layout.h"
#include "calls.h"
-#include "gimple.h"
+#include "pointer-set.h"
#include "flags.h"
#include "cp-tree.h"
#include "decl.h"
#include "c-family/c-pragma.h"
#include "dumpfile.h"
#include "intl.h"
-#include "pointer-set.h"
#include "splay-tree.h"
#include "langhooks.h"
#include "c-family/c-ada-spec.h"
+#include "asan.h"
extern cpp_reader *parse_in;
if (initp)
{
if (init)
- finish_expr_stmt (init);
+ {
+ finish_expr_stmt (init);
+ if (flag_sanitize & SANITIZE_ADDRESS)
+ {
+ struct varpool_node *vnode = varpool_get_node (decl);
+ if (vnode)
+ vnode->dynamically_initialized = 1;
+ }
+ }
/* If we're using __cxa_atexit, register a function that calls the
destructor for the object. */
tf_warning_or_error);
finish_if_stmt_cond (cond, init_if_stmt);
+ /* To make sure dynamic construction doesn't access globals from other
+ compilation units where they might not be yet constructed, for
+ -fsanitize=address insert __asan_before_dynamic_init call that
+ prevents access to either all global variables that need construction
+ in other compilation units, or at least those that haven't been
+ initialized yet. Variables that need dynamic construction in
+ the current compilation unit are kept accessible. */
+ if (flag_sanitize & SANITIZE_ADDRESS)
+ finish_expr_stmt (asan_dynamic_init_call (/*after_p=*/false));
+
node = vars;
do {
tree decl = TREE_VALUE (node);
} while (node);
+ /* Revert what __asan_before_dynamic_init did by calling
+ __asan_after_dynamic_init. */
+ if (flag_sanitize & SANITIZE_ADDRESS)
+ finish_expr_stmt (asan_dynamic_init_call (/*after_p=*/true));
+
/* Finish up the init/destruct if-stmt body. */
finish_then_clause (init_if_stmt);
finish_if_stmt (init_if_stmt);
else
gcc_unreachable ();
- pp_printf (pp, p, input_filename);
+ pp_printf (pp, p, LOCATION_FILE (input_location));
}
static void
if (DECL_P (t))
return DECL_SOURCE_LOCATION (t);
- return EXPR_LOC_OR_HERE (t);
+ return EXPR_LOC_OR_LOC (t, input_location);
}
/* Now the interfaces from error et al to dump_type et al. Each takes an
void
maybe_warn_cpp0x (cpp0x_warn_str str)
{
- if ((cxx_dialect == cxx98) && !in_system_header)
+ if ((cxx_dialect == cxx98) && !in_system_header_at (input_location))
/* We really want to suppress this warning in system headers,
because libstdc++ uses variadic templates even when we aren't
in C++0x mode. */
#define LANGSPEC (1<<1)
/* This bit is set if they did `-lm' or `-lmath'. */
#define MATHLIB (1<<2)
+/* This bit is set if they did `-lrt' or equivalent. */
+#define TIMELIB (1<<3)
/* This bit is set if they did `-lc'. */
-#define WITHLIBC (1<<3)
+#define WITHLIBC (1<<4)
/* Skip this option. */
-#define SKIPOPT (1<<4)
+#define SKIPOPT (1<<5)
#ifndef MATH_LIBRARY
#define MATH_LIBRARY "m"
#define MATH_LIBRARY_PROFILE MATH_LIBRARY
#endif
+#ifndef TIME_LIBRARY
+#define TIME_LIBRARY ""
+#endif
+
#ifndef LIBSTDCXX
#define LIBSTDCXX "stdc++"
#endif
/* "-lm" or "-lmath" if it appears on the command line. */
const struct cl_decoded_option *saw_math = NULL;
+ /* "-lrt" or eqivalent if it appears on the command line. */
+ const struct cl_decoded_option *saw_time = NULL;
+
/* "-lc" if it appears on the command line. */
const struct cl_decoded_option *saw_libc = NULL;
/* An array used to flag each argument that needs a bit set for
- LANGSPEC, MATHLIB, or WITHLIBC. */
+ LANGSPEC, MATHLIB, TIMELIB, or WITHLIBC. */
int *args;
/* By default, we throw on the math library if we have one. */
int need_math = (MATH_LIBRARY[0] != '\0');
+ /* By default, we throw on the time library if we have one. */
+ int need_time = (TIME_LIBRARY[0] != '\0');
+
/* True if we saw -static. */
int static_link = 0;
args[i] |= MATHLIB;
need_math = 0;
}
+ else if (strcmp (arg, TIME_LIBRARY) == 0)
+ {
+ args[i] |= TIMELIB;
+ need_time = 0;
+ }
else if (strcmp (arg, "c") == 0)
args[i] |= WITHLIBC;
else
saw_math = &decoded_options[i];
}
+ if (!saw_time && (args[i] & TIMELIB) && library > 0)
+ {
+ --j;
+ saw_time = &decoded_options[i];
+ }
+
if (!saw_libc && (args[i] & WITHLIBC) && library > 0)
{
--j;
added_libraries++;
j++;
}
+ if (saw_time)
+ new_decoded_options[j++] = *saw_time;
+ else if (library > 0 && need_time)
+ {
+ generate_option (OPT_l, TIME_LIBRARY, 1, CL_DRIVER,
+ &new_decoded_options[j]);
+ added_libraries++;
+ j++;
+ }
if (saw_libc)
new_decoded_options[j++] = *saw_libc;
if (shared_libgcc && !static_link)
#include "cp-tree.h"
#include "flags.h"
#include "target.h"
-#include "gimple.h"
#include "gimplify.h"
#include "wide-int.h"
TREE_READONLY (exp) = was_const;
TREE_THIS_VOLATILE (exp) = was_volatile;
TREE_TYPE (exp) = type;
- if (init)
+ /* Restore the type of init unless it was used directly. */
+ if (init && TREE_CODE (stmt_expr) != INIT_EXPR)
TREE_TYPE (init) = itype;
return stmt_expr;
}
{
if (complain & tf_error)
{
- error_at (EXPR_LOC_OR_HERE (inner_nelts),
+ error_at (EXPR_LOC_OR_LOC (inner_nelts, input_location),
"array size in operator new must be constant");
cxx_constant_value(inner_nelts);
}
&& !TREE_CONSTANT (maybe_constant_value (outer_nelts)))
{
if (complain & tf_warning_or_error)
- pedwarn(EXPR_LOC_OR_HERE (outer_nelts), OPT_Wvla,
+ pedwarn(EXPR_LOC_OR_LOC (outer_nelts, input_location), OPT_Wvla,
"ISO C++ does not support variable-length array types");
else
return error_mark_node;
}
/* Perform the overflow check. */
tree errval = TYPE_MAX_VALUE (sizetype);
- if (cxx_dialect >= cxx11)
+ if (cxx_dialect >= cxx11 && flag_exceptions)
errval = throw_bad_array_new_length ();
if (outer_nelts_check != NULL_TREE)
size = fold_build3 (COND_EXPR, sizetype, outer_nelts_check,
is big enough for all the initializers. */
if (init && TREE_CODE (init) == CONSTRUCTOR
&& CONSTRUCTOR_NELTS (init) > 0
- && !TREE_CONSTANT (maxindex))
+ && !TREE_CONSTANT (maxindex)
+ && flag_exceptions)
length_check = fold_build2 (LT_EXPR, boolean_type_node, maxindex,
size_int (CONSTRUCTOR_NELTS (init) - 1));
brace-enclosed initializers. In this case, digest_init and
store_constructor will handle the semantics for us. */
+ if (BRACE_ENCLOSED_INITIALIZER_P (init))
+ init = digest_init (atype, init, complain);
stmt_expr = build2 (INIT_EXPR, atype, base, init);
if (length_check)
stmt_expr = build3 (COND_EXPR, atype, length_check,
if (fname == error_mark_node)
return;
else if (fname == 0)
- filename = lbasename (input_filename);
+ filename = lbasename (LOCATION_FILE (input_location));
else
filename = TREE_STRING_POINTER (fname);
- finfo = get_fileinfo (input_filename);
+ finfo = get_fileinfo (LOCATION_FILE (input_location));
if (impl_file_chain == 0)
{
/* If this is zero at this point, then we are
auto-implementing. */
if (main_input_filename == 0)
- main_input_filename = input_filename;
+ main_input_filename = LOCATION_FILE (input_location);
}
finfo->interface_only = interface_strcmp (filename);
if (main_input_filename)
filename = main_input_filename;
else
- filename = input_filename;
+ filename = LOCATION_FILE (input_location);
filename = lbasename (filename);
}
else
/* Set up some flags that give proper default behavior. */
if (RECORD_OR_UNION_CODE_P (code))
{
- struct c_fileinfo *finfo = get_fileinfo (input_filename);
+ struct c_fileinfo *finfo = \
+ get_fileinfo (LOCATION_FILE (input_location));
SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, finfo->interface_unknown);
CLASSTYPE_INTERFACE_ONLY (t) = finfo->interface_only;
}
return filename_cmp (main_input_filename,
LOCATION_FILE (tl->locus)) == 0;
else
- return filename_cmp (main_input_filename, input_filename) == 0;
+ return filename_cmp (main_input_filename, LOCATION_FILE (input_location)) == 0;
}
{
scope->binding_depth = binding_depth;
indent (binding_depth);
- cp_binding_level_debug (scope, input_line, "push");
+ cp_binding_level_debug (scope, LOCATION_LINE (input_location),
+ "push");
binding_depth++;
}
}
if (ENABLE_SCOPE_CHECKING)
{
indent (--binding_depth);
- cp_binding_level_debug (scope, input_line, "leave");
+ cp_binding_level_debug (scope, LOCATION_LINE (input_location),
+ "leave");
}
/* Move one nesting level up. */
{
b->binding_depth = binding_depth;
indent (binding_depth);
- cp_binding_level_debug (b, input_line, "resume");
+ cp_binding_level_debug (b, LOCATION_LINE (input_location), "resume");
binding_depth++;
}
}
#include "langhooks.h"
#include "diagnostic-core.h"
#include "dumpfile.h"
-#include "gimple.h"
+#include "pointer-set.h"
#include "tree-iterator.h"
#include "cgraph.h"
{
/* 17.6.3.3.5 */
const char *name = UDLIT_OP_SUFFIX (id);
- if (name[0] != '_' && !in_system_header && declarator_p)
+ if (name[0] != '_' && !in_system_header_at (input_location)
+ && declarator_p)
warning (0, "literal operator suffixes not preceded by %<_%>"
" are reserved for future standardization");
}
/* Warn about old-style casts, if so requested. */
if (warn_old_style_cast
- && !in_system_header
+ && !in_system_header_at (input_location)
&& !VOID_TYPE_P (type)
&& current_lang_name != lang_name_c)
warning (OPT_Wold_style_cast, "use of old-style cast");
/* A declaration consisting of a single semicolon is
invalid. Allow it unless we're being pedantic. */
cp_lexer_consume_token (parser->lexer);
- if (!in_system_header)
+ if (!in_system_header_at (input_location))
pedwarn (input_location, OPT_Wpedantic, "extra %<;%>");
continue;
}
/* If the next token is a `}', there is a trailing comma. */
if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_BRACE))
{
- if (cxx_dialect < cxx11 && !in_system_header)
+ if (cxx_dialect < cxx11 && !in_system_header_at (input_location))
pedwarn (input_location, OPT_Wpedantic,
"comma at end of enumerator list");
break;
(void) cleanup;
if (!processing_specialization)
- parser->auto_is_implicit_function_template_parm_p = true;
+ if (!current_function_decl
+ || (current_class_type && LAMBDA_TYPE_P (current_class_type)))
+ parser->auto_is_implicit_function_template_parm_p = true;
/* Peek at the next token. */
token = cp_lexer_peek_token (parser->lexer);
/* There are no parameters. */
{
#ifndef NO_IMPLICIT_EXTERN_C
- if (in_system_header && current_class_type == NULL
+ if (in_system_header_at (input_location)
+ && current_class_type == NULL
&& current_lang_name == lang_name_c)
return NULL_TREE;
else
#if 0
/* Enable this once a lot of code has transitioned to noexcept? */
- if (cxx_dialect >= cxx11 && !in_system_header)
+ if (cxx_dialect >= cxx11 && !in_system_header_at (input_location))
warning (OPT_Wdeprecated, "dynamic exception specifications are "
"deprecated in C++0x; use %<noexcept%> instead");
#endif
{
parser->lexer->in_pragma = true;
cp_parser_omp_declare_reduction_exprs (member_function, parser);
- finish_function (0);
+ finish_function (/*inline*/2);
cp_check_omp_declare_reduction (member_function);
}
else
cp_lexer_consume_token (parser->lexer);
strcpy (p_name, "#pragma omp target");
- keep_next_level (true);
if (!flag_openmp) /* flag_openmp_simd */
return cp_parser_omp_teams (parser, pragma_tok, p_name,
OMP_TARGET_CLAUSE_MASK, cclauses);
+ keep_next_level (true);
tree sb = begin_omp_structured_block ();
unsigned save = cp_parser_begin_omp_structured_block (parser);
tree ret = cp_parser_omp_teams (parser, pragma_tok, p_name,
#include "timevar.h"
#include "tree-iterator.h"
#include "type-utils.h"
-#include "gimple.h"
#include "gimplify.h"
/* The type of functions taking a tree, and some additional data, and
tree from_type, tree arg)
{
if (explain_p)
- inform (EXPR_LOC_OR_HERE (arg),
+ inform (EXPR_LOC_OR_LOC (arg, input_location),
" cannot convert %qE (type %qT) to type %qT",
arg, from_type, to_type);
return 1;
return NULL_TREE;
expr = cxx_constant_value (expr);
if (errorcount > errs || warningcount + werrorcount > warns)
- inform (EXPR_LOC_OR_HERE (expr),
+ inform (EXPR_LOC_OR_LOC (expr, input_location),
"in template argument for type %qT ", type);
if (expr == error_mark_node)
return NULL_TREE;
new_level->decl = d;
new_level->locus = input_location;
new_level->errors = errorcount+sorrycount;
- new_level->in_system_header_p = in_system_header;
+ new_level->in_system_header_p = in_system_header_at (input_location);
new_level->next = current_tinst_level;
current_tinst_level = new_level;
pass it through tsubst. Attributes like mode, format,
cleanup and several target specific attributes expect it
unmodified. */
- else if (attribute_takes_identifier_p (get_attribute_name (t)))
+ else if (attribute_takes_identifier_p (get_attribute_name (t))
+ && TREE_VALUE (t))
{
tree chain
= tsubst_expr (TREE_CHAIN (TREE_VALUE (t)), args, complain,
fn = TREE_OPERAND (fn, 1);
if (is_overloaded_fn (fn))
fn = get_first_fn (fn);
- if (permerror (EXPR_LOC_OR_HERE (t),
+ if (permerror (EXPR_LOC_OR_LOC (t, input_location),
"%qD was not declared in this scope, "
"and no declarations were found by "
"argument-dependent lookup at the point "
/* Can't say anything more. */;
else if (DECL_CLASS_SCOPE_P (fn))
{
- inform (EXPR_LOC_OR_HERE (t),
+ location_t loc = EXPR_LOC_OR_LOC (t,
+ input_location);
+ inform (loc,
"declarations in dependent base %qT are "
"not found by unqualified lookup",
DECL_CLASS_CONTEXT (fn));
if (current_class_ptr)
- inform (EXPR_LOC_OR_HERE (t),
+ inform (loc,
"use %<this->%D%> instead", function);
else
- inform (EXPR_LOC_OR_HERE (t),
+ inform (loc,
"use %<%T::%D%> instead",
current_class_name, function);
}
/* Also deduce from the length of the initializer list. */
tree max = size_int (CONSTRUCTOR_NELTS (arg));
tree idx = compute_array_index_type (NULL_TREE, max, tf_none);
- return unify_array_domain (tparms, targs, TYPE_DOMAIN (parm),
- idx, explain_p);
+ if (TYPE_DOMAIN (parm) != NULL_TREE)
+ return unify_array_domain (tparms, targs, TYPE_DOMAIN (parm),
+ idx, explain_p);
}
/* If the std::initializer_list<T> deduction worked, replace the
;
else if (storage == ridpointers[(int) RID_EXTERN])
{
- if (!in_system_header && (cxx_dialect == cxx98))
+ if (!in_system_header_at (input_location) && (cxx_dialect == cxx98))
pedwarn (input_location, OPT_Wpedantic,
"ISO C++ 1998 forbids the use of %<extern%> on explicit "
"instantiations");
if (storage != NULL_TREE)
{
- if (!in_system_header)
+ if (!in_system_header_at (input_location))
{
if (storage == ridpointers[(int) RID_EXTERN])
{
#include "diagnostic.h"
#include "cgraph.h"
#include "tree-iterator.h"
-#include "vec.h"
#include "target.h"
-#include "gimple.h"
+#include "pointer-set.h"
+#include "hash-table.h"
#include "gimplify.h"
#include "bitmap.h"
-#include "hash-table.h"
#include "omp-low.h"
static bool verify_constant (tree, bool, bool *, bool *);
&& type_dependent_expression_p (current_class_ref)))
{
result = build_nt_call_vec (fn, *args);
- SET_EXPR_LOCATION (result, EXPR_LOC_OR_HERE (fn));
+ SET_EXPR_LOCATION (result, EXPR_LOC_OR_LOC (fn, input_location));
KOENIG_LOOKUP_P (result) = koenig_p;
if (cfun)
{
before. */
if (! TYPE_ANONYMOUS_P (t))
{
- struct c_fileinfo *finfo = get_fileinfo (input_filename);
+ struct c_fileinfo *finfo = \
+ get_fileinfo (LOCATION_FILE (input_location));
CLASSTYPE_INTERFACE_ONLY (t) = finfo->interface_only;
SET_CLASSTYPE_INTERFACE_UNKNOWN_X
(t, finfo->interface_unknown);
t = mark_rvalue_use (t);
if (!processing_template_decl)
{
+ if (TREE_CODE (OMP_CLAUSE_DECL (c)) == PARM_DECL)
+ t = maybe_constant_value (t);
t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c)))
== POINTER_TYPE)
stmt = build2 (OMP_ATOMIC, void_type_node, integer_zero_node, stmt);
OMP_ATOMIC_SEQ_CST (stmt) = seq_cst;
}
- add_stmt (stmt);
+ finish_expr_stmt (stmt);
}
void
break;
if (TREE_CODE (t) == BIND_EXPR)
{
+ if (BIND_EXPR_VARS (t))
+ {
+ ok = false;
+ break;
+ }
if (!check_constexpr_ctor_body (last, BIND_EXPR_BODY (t)))
return false;
else
bool allow_non_constant, bool addr,
bool *non_constant_p, bool *overflow_p)
{
- location_t loc = EXPR_LOC_OR_HERE (t);
+ location_t loc = EXPR_LOC_OR_LOC (t, input_location);
tree fun = get_function_named_in_call (t);
tree result;
constexpr_call new_call = { NULL, NULL, NULL, 0 };
unsigned HOST_WIDE_INT indexi = offset * BITS_PER_UNIT;
tree index = bitsize_int (indexi);
- if (offset/part_widthi <= TYPE_VECTOR_SUBPARTS (op00type))
+ if (offset / part_widthi < TYPE_VECTOR_SUBPARTS (op00type))
return fold_build3_loc (loc,
BIT_FIELD_REF, type, op00,
part_width, index);
break;
case COMPONENT_REF:
+ if (is_overloaded_fn (t))
+ {
+ /* We can only get here in checking mode via
+ build_non_dependent_expr, because any expression that
+ calls or takes the address of the function will have
+ pulled a FUNCTION_DECL out of the COMPONENT_REF. */
+ gcc_checking_assert (allow_non_constant);
+ *non_constant_p = true;
+ return t;
+ }
r = cxx_eval_component_reference (call, t, allow_non_constant, addr,
non_constant_p, overflow_p);
break;
&& !integer_zerop (op))
{
if (!allow_non_constant)
- error_at (EXPR_LOC_OR_HERE (t),
+ error_at (EXPR_LOC_OR_LOC (t, input_location),
"reinterpret_cast from integer to pointer");
*non_constant_p = true;
return t;
case EXPR_STMT:
case OFFSET_REF:
if (!allow_non_constant)
- error_at (EXPR_LOC_OR_HERE (t),
+ error_at (EXPR_LOC_OR_LOC (t, input_location),
"expression %qE is not a constant-expression", t);
*non_constant_p = true;
break;
{
if (flags & tf_error)
{
- error_at (EXPR_LOC_OR_HERE (t),
+ error_at (EXPR_LOC_OR_LOC (t, input_location),
"call to non-constexpr function %qD", fun);
explain_invalid_constexpr_fn (fun);
}
&& !integer_zerop (from))
{
if (flags & tf_error)
- error_at (EXPR_LOC_OR_HERE (t),
+ error_at (EXPR_LOC_OR_LOC (t, input_location),
"reinterpret_cast from integer to pointer");
return false;
}
#include "convert.h"
#include "cgraph.h"
#include "splay-tree.h"
-#include "gimple.h"
-#include "gimplify.h"
#include "hash-table.h"
+#include "gimple-expr.h"
+#include "gimplify.h"
#include "wide-int.h"
static tree bot_manip (tree *, int *, void *);
#include "tree.h"
#include "stor-layout.h"
#include "varasm.h"
-#include "gimple.h"
#include "cp-tree.h"
#include "flags.h"
#include "diagnostic.h"
{
tree type;
enum tree_code code;
- location_t loc = EXPR_LOC_OR_HERE (exp);
+ location_t loc = EXPR_LOC_OR_LOC (exp, input_location);
type = TREE_TYPE (exp);
if (type == error_mark_node)
rationalize_conditional_expr (enum tree_code code, tree t,
tsubst_flags_t complain)
{
+ location_t loc = EXPR_LOC_OR_LOC (t, input_location);
+
/* For MIN_EXPR or MAX_EXPR, fold-const.c has arranged things so that
the first operand is always the one to be used if both operands
are equal, so we know what conditional expression this used to be. */
gcc_assert (!TREE_SIDE_EFFECTS (op0)
&& !TREE_SIDE_EFFECTS (op1));
return
- build_conditional_expr (EXPR_LOC_OR_HERE (t),
- build_x_binary_op (EXPR_LOC_OR_HERE (t),
+ build_conditional_expr (loc,
+ build_x_binary_op (loc,
(TREE_CODE (t) == MIN_EXPR
? LE_EXPR : GE_EXPR),
op0, TREE_CODE (op0),
}
return
- build_conditional_expr (EXPR_LOC_OR_HERE (t), TREE_OPERAND (t, 0),
+ build_conditional_expr (loc, TREE_OPERAND (t, 0),
cp_build_unary_op (code, TREE_OPERAND (t, 1), 0,
complain),
cp_build_unary_op (code, TREE_OPERAND (t, 2), 0,
inc = cxx_sizeof_nowarn (TREE_TYPE (argtype));
}
else
- inc = integer_one_node;
+ inc = VECTOR_TYPE_P (argtype)
+ ? build_one_cst (argtype)
+ : integer_one_node;
inc = cp_convert (argtype, inc, complain);
&& !CONSTRUCTOR_IS_DIRECT_INIT (expr))
{
if (complain & tf_error)
- pedwarn (EXPR_LOC_OR_HERE (expr), 0, "list-initializer for "
- "non-class type must not be parenthesized");
+ pedwarn (EXPR_LOC_OR_LOC (expr, input_location), 0,
+ "list-initializer for non-class type must not "
+ "be parenthesized");
else
return error_mark_node;
}
&& TREE_CODE (TREE_TYPE (rhs)) != BOOLEAN_TYPE
&& (complain & tf_warning))
{
- location_t loc = EXPR_LOC_OR_HERE (rhs);
+ location_t loc = EXPR_LOC_OR_LOC (rhs, input_location);
warning_at (loc, OPT_Wparentheses,
"suggest parentheses around assignment used as truth value");
if (!ok)
{
if (cxx_dialect >= cxx11)
- pedwarn (EXPR_LOC_OR_HERE (init), OPT_Wnarrowing,
+ pedwarn (EXPR_LOC_OR_LOC (init, input_location), OPT_Wnarrowing,
"narrowing conversion of %qE from %qT to %qT inside { }",
init, ftype, type);
else
- warning_at (EXPR_LOC_OR_HERE (init), OPT_Wnarrowing,
+ warning_at (EXPR_LOC_OR_LOC (init, input_location), OPT_Wnarrowing,
"narrowing conversion of %qE from %qT to %qT inside { } "
"is ill-formed in C++11", init, ftype, type);
}
#include "cgraph.h"
#include "tree-iterator.h"
#include "vtable-verify.h"
-#include "gimple.h"
#include "gimplify.h"
#include "stringpool.h"
#include "stor-layout.h"
#include "coretypes.h"
#include "diagnostic.h"
#include "tree.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "data-streamer.h"
#include "system.h"
#include "coretypes.h"
#include "tree.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "data-streamer.h"
#include "system.h"
#include "coretypes.h"
#include "tree.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "data-streamer.h"
dbxout_type (TREE_TYPE (type), 0);
break;
- case POINTER_BOUNDS_TYPE:
- /* No debug info for pointer bounds type supported yet. */
- break;
-
default:
gcc_unreachable ();
}
* x86 specific memory model extensions for transactional memory:: x86 memory models.
* Object Size Checking:: Built-in functions for limited buffer overflow
checking.
-* Pointer Bounds Checker builtins:: Built-in functions for Pointer Bounds Checker.
* Cilk Plus Builtins:: Built-in functions for the Cilk Plus language extension.
* Other Builtins:: Other built-in functions.
* Target Builtins:: Built-in functions specific to particular targets.
@code{returns_nonnull}, @code{gnu_inline},
@code{externally_visible}, @code{hot}, @code{cold}, @code{artificial},
@code{no_sanitize_address}, @code{no_address_safety_analysis},
-@code{no_sanitize_undefined}, @code{bnd_legacy},
+@code{no_sanitize_undefined},
@code{error} and @code{warning}.
Several other attributes are defined for functions on particular
target systems. Other attributes, including @code{section} are
to inform the compiler that it should not check for undefined behavior
in the function when compiling with the @option{-fsanitize=undefined} option.
-@item bnd_legacy
-@cindex @code{bnd_legacy} function attribute
-The @code{bnd_legacy} attribute on functions is used to inform
-compiler that function should not be instrumented when compiled
-with @option{-fcheck-pointers} option.
-
@item regparm (@var{number})
@cindex @code{regparm} attribute
@cindex functions that are passed arguments in registers on the 386
The keyword @code{__attribute__} allows you to specify special
attributes of @code{struct} and @code{union} types when you define
such types. This keyword is followed by an attribute specification
-inside double parentheses. Eight attributes are currently defined for
+inside double parentheses. Seven attributes are currently defined for
types: @code{aligned}, @code{packed}, @code{transparent_union},
-@code{unused}, @code{deprecated}, @code{visibility}, @code{may_alias}
-and @code{bnd_variable_size}. Other attributes are defined for
-functions (@pxref{Function Attributes}) and for variables
-(@pxref{Variable Attributes}).
+@code{unused}, @code{deprecated}, @code{visibility}, and
+@code{may_alias}. Other attributes are defined for functions
+(@pxref{Function Attributes}) and for variables (@pxref{Variable
+Attributes}).
You may also specify any one of these attributes with @samp{__}
preceding and following its keyword. This allows you to use these
Otherwise the two shared objects are unable to use the same
typeinfo node and exception handling will break.
-@item bnd_variable_size
-When applied to a structure field, this attribute tells Pointer
-Bounds Checker that the size of this field should not be computed
-using static type information. It may be used to mark variable
-sized static array fields placed at the end of a structure.
-
-@smallexample
-struct S
-@{
- int size;
- char data[1];
-@}
-S *p = (S *)malloc (sizeof(S) + 100);
-p->data[10] = 0; //Bounds violation
-@end smallexample
-
-By using an attribute for a field we may avoid bound violation
-we most probably do not want to see:
-
-@smallexample
-struct S
-@{
- int size;
- char data[1] __attribute__((bnd_variable_size));
-@}
-S *p = (S *)malloc (sizeof(S) + 100);
-p->data[10] = 0; //OK
-@end smallexample
-
@end table
To specify multiple attributes, separate them by commas within the
@code{fputc} etc.@: functions, it does, otherwise the checking function
is called and the @var{flag} argument passed to it.
-@node Pointer Bounds Checker builtins
-@section Pointer Bounds Checker Built-in Functions
-@findex __builtin___bnd_set_ptr_bounds
-@findex __builtin___bnd_narrow_ptr_bounds
-@findex __builtin___bnd_copy_ptr_bounds
-@findex __builtin___bnd_init_ptr_bounds
-@findex __builtin___bnd_null_ptr_bounds
-@findex __builtin___bnd_store_ptr_bounds
-@findex __builtin___bnd_chk_ptr_lbounds
-@findex __builtin___bnd_chk_ptr_ubounds
-@findex __builtin___bnd_chk_ptr_bounds
-@findex __builtin___bnd_get_ptr_lbound
-@findex __builtin___bnd_get_ptr_ubound
-
-GCC provides a set of built-in functions to control Pointer Bounds Checker
-instrumentation. Note that all Pointer Bounds Checker builtins are allowed
-to use even if you compile with Pointer Bounds Checker off. But functions
-behavior may differ in such case.
-
-@deftypefn {Built-in Function} void * __builtin___bnd_set_ptr_bounds (const void * @var{q}, size_t @var{size})
-
-This built-in function returns a new pointer with the value of @var{q}, and
-associate it with the bounds [@var{q}, @var{q}+@var{size}-1]. With Pointer
-Bounds Checker off built-in function just returns the first argument.
-
-@smallexample
-extern void *__wrap_malloc (size_t n)
-@{
- void *p = (void *)__real_malloc (n);
- if (!p) return __builtin___bnd_null_ptr_bounds (p);
- return __builtin___bnd_set_ptr_bounds (p, n);
-@}
-@end smallexample
-
-@end deftypefn
-
-@deftypefn {Built-in Function} void * __builtin___bnd_narrow_ptr_bounds (const void * @var{p}, const void * @var{q}, size_t @var{size})
-
-This built-in function returns a new pointer with the value of @var{p}
-and associate it with the narrowed bounds formed by the intersection
-of bounds associated with @var{q} and the [@var{p}, @var{p} + @var{size} - 1].
-With Pointer Bounds Checker off built-in function just returns the first
-argument.
-
-@smallexample
-void init_objects (object *objs, size_t size)
-@{
- size_t i;
- /* Initialize objects one-by-one passing pointers with bounds of an object,
- not the full array of objects. */
- for (i = 0; i < size; i++)
- init_object (__builtin___bnd_narrow_ptr_bounds (objs + i, objs, sizeof(object)));
-@}
-@end smallexample
-
-@end deftypefn
-
-@deftypefn {Built-in Function} void * __builtin___bnd_copy_ptr_bounds (const void * @var{q}, const void * @var{r})
-
-This built-in function returns a new pointer with the value of @var{q},
-and associate it with the bounds already associated with pointer @var{r}.
-With Pointer Bounds Checker off built-in function just returns the first
-argument.
-
-@smallexample
-/* Here is a way to get pointer to object's field but
- still with the full object's bounds. */
-int *field_ptr = __builtin___bnd_copy_ptr_bounds (&objptr->int_filed, objptr);
-@end smallexample
-
-@end deftypefn
-
-@deftypefn {Built-in Function} void * __builtin___bnd_init_ptr_bounds (const void * @var{q})
-
-This built-in function returns a new pointer with the value of @var{q}, and
-associate it with INIT (allowing full memory access) bounds. With Pointer
-Bounds Checker off built-in function just returns the first argument.
-
-@end deftypefn
-
-@deftypefn {Built-in Function} void * __builtin___bnd_null_ptr_bounds (const void * @var{q})
-
-This built-in function returns a new pointer with the value of @var{q}, and
-associate it with NULL (allowing no memory access) bounds. With Pointer
-Bounds Checker off built-in function just returns the first argument.
-
-@end deftypefn
-
-@deftypefn {Built-in Function} void __builtin___bnd_store_ptr_bounds (const void ** @var{ptr_addr}, const void * @var{ptr_val})
-
-This built-in function stores the bounds associated with pointer @var{ptr_val}
-and location @var{ptr_addr} into Bounds Table. This can be useful to propagate
-bounds from legacy code without touching the associated pointer's memory when
-pointers were copied as integers. With Pointer Bounds Checker off built-in
-function call is ignored.
-
-@end deftypefn
-
-@deftypefn {Built-in Function} void __builtin___bnd_chk_ptr_lbounds (const void * @var{q})
-
-This built-in function checks if the pointer @var{q} is within the lower
-bound of its associated bounds. With Pointer Bounds Checker off built-in
-function call is ignored.
-
-@smallexample
-extern void *__wrap_memset (void *dst, int c, size_t len)
-@{
- if (len > 0)
- @{
- __builtin___bnd_chk_ptr_lbounds (dst);
- __builtin___bnd_chk_ptr_ubounds ((char *)dst + len - 1);
- __real_memset (dst, c, len);
- @}
- return dst;
-@}
-@end smallexample
-
-@end deftypefn
-
-@deftypefn {Built-in Function} void __builtin___bnd_chk_ptr_ubounds (const void * @var{q})
-
-This built-in function checks if the pointer @var{q} is within the upper
-bound of its associated bounds. With Pointer Bounds Checker off built-in
-function call is ignored.
-
-@end deftypefn
-
-@deftypefn {Built-in Function} void __builtin___bnd_chk_ptr_bounds (const void * @var{q}, size_t @var{size})
-
-This built-in function checks if [@var{q}, @var{q} + @var{size} - 1] is within
-the lower and upper bounds associated with @var{q}. With Pointer Bounds Checker
-off built-in function call is ignored.
-
-@smallexample
-extern void *__wrap_memcpy (void *dst, const void *src, size_t n)
-@{
- if (n > 0)
- @{
- __bnd_chk_ptr_bounds (dst, n);
- __bnd_chk_ptr_bounds (src, n);
- __real_memcpy (dst, src, n);
- @}
- return dst;
-@}
-@end smallexample
-
-@end deftypefn
-
-@deftypefn {Built-in Function} const void * __builtin___bnd_get_ptr_lbound (const void * @var{q})
-
-This built-in function returns the lower bound (which is a pointer) associated
-with the pointer @var{q}. This is at least useful for debugging using printf.
-With Pointer Bounds Checker off built-in function returns 0.
-
-@smallexample
-void *lb = __builtin___bnd_get_ptr_lbound (q);
-void *ub = __builtin___bnd_get_ptr_ubound (q);
-printf ("q = %p lb(q) = %p ub(q) = %p", q, lb, ub);
-@end smallexample
-
-@end deftypefn
-
-@deftypefn {Built-in Function} const void * __builtin___bnd_get_ptr_ubound (const void * @var{q})
-
-This built-in function returns the upper bound (which is a pointer) associated
-with the pointer @var{q}. With Pointer Bounds Checker off built-in function
-returns -1.
-
-@end deftypefn
-
@node Cilk Plus Builtins
@section Cilk Plus C/C++ language extension Built-in Functions.
A conforming implementation of ISO C is required to document its
choice of behavior in each of the areas that are designated
``implementation defined''. The following lists all such areas,
-along with the section numbers from the ISO/IEC 9899:1990 and ISO/IEC
-9899:1999 standards. Some areas are only implementation-defined in
-one version of the standard.
+along with the section numbers from the ISO/IEC 9899:1990, ISO/IEC
+9899:1999 and ISO/IEC 9899:2011 standards. Some areas are only
+implementation-defined in one version of the standard.
Some choices depend on the externally determined ABI for the platform
(including standard character encodings) which GCC follows; these are
@itemize @bullet
@item
-@cite{How a diagnostic is identified (C90 3.7, C99 3.10, C90 and C99 5.1.1.3).}
+@cite{How a diagnostic is identified (C90 3.7, C99 and C11 3.10, C90,
+C99 and C11 5.1.1.3).}
Diagnostics consist of all the output sent to stderr by GCC@.
@item
@cite{Whether each nonempty sequence of white-space characters other than
new-line is retained or replaced by one space character in translation
-phase 3 (C90 and C99 5.1.1.2).}
+phase 3 (C90, C99 and C11 5.1.1.2).}
@xref{Implementation-defined behavior, , Implementation-defined
behavior, cpp, The C Preprocessor}.
@itemize @bullet
@item
@cite{The mapping between physical source file multibyte characters
-and the source character set in translation phase 1 (C90 and C99 5.1.1.2).}
+and the source character set in translation phase 1 (C90, C99 and C11
+5.1.1.2).}
@xref{Implementation-defined behavior, , Implementation-defined
behavior, cpp, The C Preprocessor}.
@itemize @bullet
@item
@cite{Which additional multibyte characters may appear in identifiers
-and their correspondence to universal character names (C99 6.4.2).}
+and their correspondence to universal character names (C99 and C11 6.4.2).}
@xref{Implementation-defined behavior, , Implementation-defined
behavior, cpp, The C Preprocessor}.
@item
@cite{The number of significant initial characters in an identifier
-(C90 6.1.2, C90 and C99 5.2.4.1, C99 6.4.2).}
+(C90 6.1.2, C90, C99 and C11 5.2.4.1, C99 and C11 6.4.2).}
For internal names, all characters are significant. For external names,
the number of significant characters are defined by the linker; for
@cite{Whether case distinctions are significant in an identifier with
external linkage (C90 6.1.2).}
-This is a property of the linker. C99 requires that case distinctions
+This is a property of the linker. C99 and C11 require that case distinctions
are always significant in identifiers with external linkage and
systems without this property are not supported by GCC@.
@itemize @bullet
@item
-@cite{The number of bits in a byte (C90 3.4, C99 3.6).}
+@cite{The number of bits in a byte (C90 3.4, C99 and C11 3.6).}
Determined by ABI@.
@item
-@cite{The values of the members of the execution character set (C90
-and C99 5.2.1).}
+@cite{The values of the members of the execution character set (C90,
+C99 and C11 5.2.1).}
Determined by ABI@.
@item
@cite{The unique value of the member of the execution character set produced
-for each of the standard alphabetic escape sequences (C90 and C99 5.2.2).}
+for each of the standard alphabetic escape sequences (C90, C99 and C11
+5.2.2).}
Determined by ABI@.
@item
@cite{The value of a @code{char} object into which has been stored any
character other than a member of the basic execution character set
-(C90 6.1.2.5, C99 6.2.5).}
+(C90 6.1.2.5, C99 and C11 6.2.5).}
Determined by ABI@.
@item
@cite{Which of @code{signed char} or @code{unsigned char} has the same
range, representation, and behavior as ``plain'' @code{char} (C90
-6.1.2.5, C90 6.2.1.1, C99 6.2.5, C99 6.3.1.1).}
+6.1.2.5, C90 6.2.1.1, C99 and C11 6.2.5, C99 and C11 6.3.1.1).}
@opindex fsigned-char
@opindex funsigned-char
@item
@cite{The mapping of members of the source character set (in character
constants and string literals) to members of the execution character
-set (C90 6.1.3.4, C99 6.4.4.4, C90 and C99 5.1.1.2).}
+set (C90 6.1.3.4, C99 and C11 6.4.4.4, C90, C99 and C11 5.1.1.2).}
Determined by ABI@.
@item
@cite{The value of an integer character constant containing more than one
character or containing a character or escape sequence that does not map
-to a single-byte execution character (C90 6.1.3.4, C99 6.4.4.4).}
+to a single-byte execution character (C90 6.1.3.4, C99 and C11 6.4.4.4).}
@xref{Implementation-defined behavior, , Implementation-defined
behavior, cpp, The C Preprocessor}.
@item
@cite{The value of a wide character constant containing more than one
-multibyte character, or containing a multibyte character or escape
-sequence not represented in the extended execution character set (C90
-6.1.3.4, C99 6.4.4.4).}
+multibyte character or a single multibyte character that maps to
+multiple members of the extended execution character set, or
+containing a multibyte character or escape sequence not represented in
+the extended execution character set (C90 6.1.3.4, C99 and C11
+6.4.4.4).}
@xref{Implementation-defined behavior, , Implementation-defined
behavior, cpp, The C Preprocessor}.
@cite{The current locale used to convert a wide character constant consisting
of a single multibyte character that maps to a member of the extended
execution character set into a corresponding wide character code (C90
-6.1.3.4, C99 6.4.4.4).}
+6.1.3.4, C99 and C11 6.4.4.4).}
@xref{Implementation-defined behavior, , Implementation-defined
behavior, cpp, The C Preprocessor}.
+@item
+@cite{Whether differently-prefixed wide string literal tokens can be
+concatenated and, if so, the treatment of the resulting multibyte
+character sequence (C11 6.4.5).}
+
+Such tokens may not be concatenated.
+
@item
@cite{The current locale used to convert a wide string literal into
-corresponding wide character codes (C90 6.1.4, C99 6.4.5).}
+corresponding wide character codes (C90 6.1.4, C99 and C11 6.4.5).}
@xref{Implementation-defined behavior, , Implementation-defined
behavior, cpp, The C Preprocessor}.
@item
@cite{The value of a string literal containing a multibyte character or escape
-sequence not represented in the execution character set (C90 6.1.4, C99 6.4.5).}
+sequence not represented in the execution character set (C90 6.1.4,
+C99 and C11 6.4.5).}
@xref{Implementation-defined behavior, , Implementation-defined
behavior, cpp, The C Preprocessor}.
+
+@item
+@cite{The encoding of any of @code{wchar_t}, @code{char16_t}, and
+@code{char32_t} where the corresponding standard encoding macro
+(@code{__STDC_ISO_10646__}, @code{__STDC_UTF_16__}, or
+@code{__STDC_UTF_32__}) is not defined (C11 6.10.8.2).}
+
+@xref{Implementation-defined behavior, , Implementation-defined
+behavior, cpp, The C Preprocessor}. @code{char16_t} and
+@code{char32_t} literals are always encoded in UTF-16 and UTF-32
+respectively.
+
@end itemize
@node Integers implementation
@itemize @bullet
@item
-@cite{Any extended integer types that exist in the implementation (C99 6.2.5).}
+@cite{Any extended integer types that exist in the implementation (C99
+and C11 6.2.5).}
GCC does not support any extended integer types.
@c The __mode__ attribute might create types of precisions not
@item
@cite{Whether signed integer types are represented using sign and magnitude,
two's complement, or one's complement, and whether the extraordinary value
-is a trap representation or an ordinary value (C99 6.2.6.2).}
+is a trap representation or an ordinary value (C99 and C11 6.2.6.2).}
GCC supports only two's complement integer types, and all bit patterns
are ordinary values.
@item
@cite{The rank of any extended integer type relative to another extended
-integer type with the same precision (C99 6.3.1.1).}
+integer type with the same precision (C99 and C11 6.3.1.1).}
GCC does not support any extended integer types.
@c If it did, there would only be one of each precision and signedness.
@item
@cite{The result of, or the signal raised by, converting an integer to a
signed integer type when the value cannot be represented in an object of
-that type (C90 6.2.1.2, C99 6.3.1.3).}
+that type (C90 6.2.1.2, C99 and C11 6.3.1.3).}
For conversion to a type of width @math{N}, the value is reduced
modulo @math{2^N} to be within range of the type; no signal is raised.
@item
@cite{The results of some bitwise operations on signed integers (C90
-6.3, C99 6.5).}
+6.3, C99 and C11 6.5).}
Bitwise operators act on the representation of the value including
both the sign and value bits, where the sign bit is considered
immediately above the highest-value value bit. Signed @samp{>>} acts
on negative numbers by sign extension.
-GCC does not use the latitude given in C99 only to treat certain
+GCC does not use the latitude given in C99 and C11 only to treat certain
aspects of signed @samp{<<} as undefined, but this is subject to
change.
@item
@cite{The sign of the remainder on integer division (C90 6.3.5).}
-GCC always follows the C99 requirement that the result of division is
+GCC always follows the C99 and C11 requirement that the result of division is
truncated towards zero.
@end itemize
@item
@cite{The accuracy of the floating-point operations and of the library
functions in @code{<math.h>} and @code{<complex.h>} that return floating-point
-results (C90 and C99 5.2.4.2.2).}
+results (C90, C99 and C11 5.2.4.2.2).}
The accuracy is unknown.
@item
@cite{The rounding behaviors characterized by non-standard values
of @code{FLT_ROUNDS} @gol
-(C90 and C99 5.2.4.2.2).}
+(C90, C99 and C11 5.2.4.2.2).}
GCC does not use such values.
@item
@cite{The evaluation methods characterized by non-standard negative
-values of @code{FLT_EVAL_METHOD} (C99 5.2.4.2.2).}
+values of @code{FLT_EVAL_METHOD} (C99 and C11 5.2.4.2.2).}
GCC does not use such values.
@item
@cite{The direction of rounding when an integer is converted to a
floating-point number that cannot exactly represent the original
-value (C90 6.2.1.3, C99 6.3.1.4).}
+value (C90 6.2.1.3, C99 and C11 6.3.1.4).}
C99 Annex F is followed.
@item
@cite{The direction of rounding when a floating-point number is
-converted to a narrower floating-point number (C90 6.2.1.4, C99
+converted to a narrower floating-point number (C90 6.2.1.4, C99 and C11
6.3.1.5).}
C99 Annex F is followed.
@item
@cite{How the nearest representable value or the larger or smaller
representable value immediately adjacent to the nearest representable
-value is chosen for certain floating constants (C90 6.1.3.1, C99
+value is chosen for certain floating constants (C90 6.1.3.1, C99 and C11
6.4.4.2).}
C99 Annex F is followed.
@item
@cite{Whether and how floating expressions are contracted when not
-disallowed by the @code{FP_CONTRACT} pragma (C99 6.5).}
+disallowed by the @code{FP_CONTRACT} pragma (C99 and C11 6.5).}
-Expressions are currently only contracted if
+Expressions are currently only contracted if @option{-ffp-contract=fast},
@option{-funsafe-math-optimizations} or @option{-ffast-math} are used.
This is subject to change.
@item
-@cite{The default state for the @code{FENV_ACCESS} pragma (C99 7.6.1).}
+@cite{The default state for the @code{FENV_ACCESS} pragma (C99 and C11
+7.6.1).}
This pragma is not implemented, but the default is to ``off'' unless
@option{-frounding-math} is used in which case it is ``on''.
@item
@cite{Additional floating-point exceptions, rounding modes, environments,
-and classifications, and their macro names (C99 7.6, C99 7.12).}
+and classifications, and their macro names (C99 and C11 7.6, C99 and
+C11 7.12).}
This is dependent on the implementation of the C library, and is not
defined by GCC itself.
@item
-@cite{The default state for the @code{FP_CONTRACT} pragma (C99 7.12.2).}
+@cite{The default state for the @code{FP_CONTRACT} pragma (C99 and C11
+7.12.2).}
This pragma is not implemented. Expressions are currently only
-contracted if @option{-funsafe-math-optimizations} or
-@option{-ffast-math} are used. This is subject to change.
+contracted if @option{-ffp-contract=fast},
+@option{-funsafe-math-optimizations} or @option{-ffast-math} are used.
+This is subject to change.
@item
@cite{Whether the ``inexact'' floating-point exception can be raised
@itemize @bullet
@item
@cite{The result of converting a pointer to an integer or
-vice versa (C90 6.3.4, C99 6.3.2.3).}
+vice versa (C90 6.3.4, C99 and C11 6.3.2.3).}
A cast from pointer to integer discards most-significant bits if the
pointer representation is larger than the integer type,
pointer must reference the same object as the original pointer, otherwise
the behavior is undefined. That is, one may not use integer arithmetic to
avoid the undefined behavior of pointer arithmetic as proscribed in
-C99 6.5.6/8.
+C99 and C11 6.5.6/8.
@item
@cite{The size of the result of subtracting two pointers to elements
-of the same array (C90 6.3.6, C99 6.5.6).}
+of the same array (C90 6.3.6, C99 and C11 6.5.6).}
The value is as specified in the standard and the type is determined
by the ABI@.
@itemize @bullet
@item
@cite{The extent to which suggestions made by using the @code{register}
-storage-class specifier are effective (C90 6.5.1, C99 6.7.1).}
+storage-class specifier are effective (C90 6.5.1, C99 and C11 6.7.1).}
The @code{register} specifier affects code generation only in these ways:
@item
@cite{The extent to which suggestions made by using the inline function
-specifier are effective (C99 6.7.4).}
+specifier are effective (C99 and C11 6.7.4).}
GCC will not inline any functions if the @option{-fno-inline} option is
used or if @option{-O0} is used. Otherwise, GCC may still be unable to
@item
@cite{Whether a ``plain'' @code{int} bit-field is treated as a
@code{signed int} bit-field or as an @code{unsigned int} bit-field
-(C90 6.5.2, C90 6.5.2.1, C99 6.7.2, C99 6.7.2.1).}
+(C90 6.5.2, C90 6.5.2.1, C99 and C11 6.7.2, C99 and C11 6.7.2.1).}
@opindex funsigned-bitfields
By default it is treated as @code{signed int} but this may be changed
@item
@cite{Allowable bit-field types other than @code{_Bool}, @code{signed int},
-and @code{unsigned int} (C99 6.7.2.1).}
+and @code{unsigned int} (C99 and C11 6.7.2.1).}
No other types are permitted in strictly conforming mode.
@c Would it be better to restrict the pedwarn for other types to C90
-@c mode and document the other types for C99 mode?
+@c mode and document the other types for C99/C11 mode?
+
+@item
+@cite{Whether atomic types are permitted for bit-fields (C11 6.7.2.1).}
+
+Atomic types are not permitted for bit-fields.
@item
@cite{Whether a bit-field can straddle a storage-unit boundary (C90
-6.5.2.1, C99 6.7.2.1).}
+6.5.2.1, C99 and C11 6.7.2.1).}
Determined by ABI@.
@item
@cite{The order of allocation of bit-fields within a unit (C90
-6.5.2.1, C99 6.7.2.1).}
+6.5.2.1, C99 and C11 6.7.2.1).}
Determined by ABI@.
@item
@cite{The alignment of non-bit-field members of structures (C90
-6.5.2.1, C99 6.7.2.1).}
+6.5.2.1, C99 and C11 6.7.2.1).}
Determined by ABI@.
@item
@cite{The integer type compatible with each enumerated type (C90
-6.5.2.2, C99 6.7.2.2).}
+6.5.2.2, C99 and C11 6.7.2.2).}
@opindex fshort-enums
Normally, the type is @code{unsigned int} if there are no negative
@itemize @bullet
@item
@cite{What constitutes an access to an object that has volatile-qualified
-type (C90 6.5.3, C99 6.7.3).}
+type (C90 6.5.3, C99 and C11 6.7.3).}
Such an object is normally accessed by pointers and used for accessing
hardware. In most expressions, it is intuitively obvious what is a read
implementation-defined behavior.
@itemize @bullet
+@item
+@cite{The locations within @code{#pragma} directives where header name
+preprocessing tokens are recognized (C11 6.4, C11 6.4.7).}
+
@item
@cite{How sequences in both forms of header names are mapped to headers
-or external source file names (C90 6.1.7, C99 6.4.7).}
+or external source file names (C90 6.1.7, C99 and C11 6.4.7).}
@item
@cite{Whether the value of a character constant in a constant expression
that controls conditional inclusion matches the value of the same character
-constant in the execution character set (C90 6.8.1, C99 6.10.1).}
+constant in the execution character set (C90 6.8.1, C99 and C11 6.10.1).}
@item
@cite{Whether the value of a single-character character constant in a
constant expression that controls conditional inclusion may have a
-negative value (C90 6.8.1, C99 6.10.1).}
+negative value (C90 6.8.1, C99 and C11 6.10.1).}
@item
@cite{The places that are searched for an included @samp{<>} delimited
header, and how the places are specified or the header is
-identified (C90 6.8.2, C99 6.10.2).}
+identified (C90 6.8.2, C99 and C11 6.10.2).}
@item
@cite{How the named source file is searched for in an included @samp{""}
-delimited header (C90 6.8.2, C99 6.10.2).}
+delimited header (C90 6.8.2, C99 and C11 6.10.2).}
@item
@cite{The method by which preprocessing tokens (possibly resulting from
macro expansion) in a @code{#include} directive are combined into a header
-name (C90 6.8.2, C99 6.10.2).}
+name (C90 6.8.2, C99 and C11 6.10.2).}
@item
@cite{The nesting limit for @code{#include} processing (C90 6.8.2, C99
-6.10.2).}
+and C11 6.10.2).}
@item
@cite{Whether the @samp{#} operator inserts a @samp{\} character before
the @samp{\} character that begins a universal character name in a
-character constant or string literal (C99 6.10.3.2).}
+character constant or string literal (C99 and C11 6.10.3.2).}
@item
@cite{The behavior on each recognized non-@code{STDC #pragma}
-directive (C90 6.8.6, C99 6.10.6).}
+directive (C90 6.8.6, C99 and C11 6.10.6).}
@xref{Pragmas, , Pragmas, cpp, The C Preprocessor}, for details of
pragmas accepted by GCC on all targets. @xref{Pragmas, , Pragmas
@item
@cite{The definitions for @code{__DATE__} and @code{__TIME__} when
respectively, the date and time of translation are not available (C90
-6.8.8, C99 6.10.8).}
+6.8.8, C99 6.10.8, C11 6.10.8.1).}
@end itemize
@itemize @bullet
@item
@cite{The null pointer constant to which the macro @code{NULL} expands
-(C90 7.1.6, C99 7.17).}
+(C90 7.1.6, C99 7.17, C11 7.19).}
In @code{<stddef.h>}, @code{NULL} expands to @code{((void *)0)}. GCC
does not provide the other headers which define @code{NULL} and some
@item
@cite{The values or expressions assigned to the macros specified in the
headers @code{<float.h>}, @code{<limits.h>}, and @code{<stdint.h>}
-(C90 and C99 5.2.4.2, C99 7.18.2, C99 7.18.3).}
+(C90, C99 and C11 5.2.4.2, C99 7.18.2, C99 7.18.3, C11 7.20.2, C11 7.20.3).}
Determined by ABI@.
+@item
+@cite{The result of attempting to indirectly access an object with
+automatic or thread storage duration from a thread other than the one
+with which it is associated (C11 6.2.4).}
+
+Such accesses are supported, subject to the same requirements for
+synchronization for concurrent accesses as for concurrent accesses to
+any object.
+
@item
@cite{The number, order, and encoding of bytes in any object
-(when not explicitly specified in this International Standard) (C99 6.2.6.1).}
+(when not explicitly specified in this International Standard) (C99
+and C11 6.2.6.1).}
Determined by ABI@.
@item
-@cite{The value of the result of the @code{sizeof} operator (C90
-6.3.3.4, C99 6.5.3.4).}
+@cite{Whether any extended alignments are supported and the contexts
+in which they are supported (C11 6.2.8).}
+
+Extended alignments up to @math{2^{28}} (bytes) are supported for
+objects of automatic storage duration. Alignments supported for
+objects of static and thread storage duration are determined by the
+ABI.
+
+@item
+@cite{Valid alignment values other than those returned by an _Alignof
+expression for fundamental types, if any (C11 6.2.8).}
+
+Valid alignments are powers of 2 up to and including @math{2^{28}}.
+
+@item
+@cite{The value of the result of the @code{sizeof} and @code{_Alignof}
+operators (C90 6.3.3.4, C99 and C11 6.5.3.4).}
Determined by ABI@.
-Wlogical-op -Wlong-long @gol
-Wmain -Wmaybe-uninitialized -Wmissing-braces -Wmissing-field-initializers @gol
-Wmissing-include-dirs @gol
--Wno-multichar -Wnonnull -Wno-overflow @gol
+-Wno-multichar -Wnonnull -Wno-overflow -Wopenmp-simd @gol
-Woverlength-strings -Wpacked -Wpacked-bitfield-compat -Wpadded @gol
-Wparentheses -Wpedantic-ms-format -Wno-pedantic-ms-format @gol
-Wpointer-arith -Wno-pointer-to-int-cast @gol
@gccoptlist{@var{object-file-name} -l@var{library} @gol
-nostartfiles -nodefaultlibs -nostdlib -pie -rdynamic @gol
-s -static -static-libgcc -static-libstdc++ @gol
--static-libasan -static-libtsan -static-libubsan @gol
+-static-libasan -static-libtsan -static-liblsan -static-libubsan @gol
-shared -shared-libgcc -symbolic @gol
-T @var{script} -Wl,@var{option} -Xlinker @var{option} @gol
-u @var{symbol}}
-mfix-cortex-m3-ldrd @gol
-munaligned-access @gol
-mneon-for-64bits @gol
+-mslow-flash-data @gol
-mrestrict-it}
@emph{AVR Options}
-mavx2 -mavx512f -mavx512pf -mavx512er -mavx512cd @gol
-maes -mpclmul -mfsgsbase -mrdrnd -mf16c -mfma @gol
-msse4a -m3dnow -mpopcnt -mabm -mbmi -mtbm -mfma4 -mxop -mlzcnt @gol
--mbmi2 -mfxsr -mxsave -mxsaveopt -mrtm -mlwp -mmpx -mthreads @gol
+-mbmi2 -mfxsr -mxsave -mxsaveopt -mrtm -mlwp -mthreads @gol
-mno-align-stringops -minline-all-stringops @gol
-minline-stringops-dynamically -mstringop-strategy=@var{alg} @gol
-mmemcpy-strategy=@var{strategy} -mmemset-strategy=@var{strategy}
@samp{gdb --args cc1 @dots{}}.
@item -fplugin=@var{name}.so
+@opindex fplugin
Load the plugin code in file @var{name}.so, assumed to be a
shared object to be dlopen'd by the compiler. The base name of
the shared object file is used to identify the plugin for the
Plugins API.
@item -fplugin-arg-@var{name}-@var{key}=@var{value}
+@opindex fplugin-arg
Define an argument called @var{key} with a value of @var{value}
for the plugin called @var{name}.
@item -fdump-ada-spec@r{[}-slim@r{]}
+@opindex fdump-ada-spec
For C and C++ source and include files, generate corresponding Ada
specs. @xref{Generating Ada Bindings for C and C++ headers,,, gnat_ugn,
GNAT User's Guide}, which provides detailed documentation on this feature.
@item -fdump-go-spec=@var{file}
+@opindex fdump-go-spec
For input files in any language, generate corresponding Go
declarations in @var{file}. This generates Go @code{const},
@code{type}, @code{var}, and @code{func} declarations which may be a
@itemx c9x
@itemx iso9899:1999
@itemx iso9899:199x
-ISO C99. Note that this standard is not yet fully supported; see
+ISO C99. This standard is substantially completely supported, modulo
+bugs, extended identifiers (supported except for corner cases when
+@option{-fextended-identifiers} is used) and floating-point issues
+(mainly but not entirely relating to optional C99 features from
+Annexes F and G). See
@w{@uref{http://gcc.gnu.org/c99status.html}} for more information. The
names @samp{c9x} and @samp{iso9899:199x} are deprecated.
@item c11
@itemx c1x
@itemx iso9899:2011
-ISO C11, the 2011 revision of the ISO C standard.
-Support is incomplete and experimental. The name @samp{c1x} is
-deprecated.
+ISO C11, the 2011 revision of the ISO C standard. This standard is
+substantially completely supported, modulo bugs, extended identifiers
+(supported except for corner cases when
+@option{-fextended-identifiers} is used), floating-point issues
+(mainly but not entirely relating to optional C11 features from
+Annexes F and G) and the optional Annexes K (Bounds-checking
+interfaces) and L (Analyzability). The name @samp{c1x} is deprecated.
@item gnu90
@itemx gnu89
@item gnu99
@itemx gnu9x
-GNU dialect of ISO C99. When ISO C99 is fully implemented in GCC,
-this will become the default. The name @samp{gnu9x} is deprecated.
+GNU dialect of ISO C99. The name @samp{gnu9x} is deprecated.
@item gnu11
@itemx gnu1x
-GNU dialect of ISO C11. Support is incomplete and experimental. The
-name @samp{gnu1x} is deprecated.
+GNU dialect of ISO C11. This is intended to become the default in a
+future release of GCC. The name @samp{gnu1x} is deprecated.
@item c++98
@itemx c++03
comments, after the declaration.
@item -fallow-parameterless-variadic-functions
+@opindex fallow-parameterless-variadic-functions
Accept variadic functions without named parameters.
Although it is possible to define such a function, this is not very
file, be sure to delete any existing one.
@item -fvtv-counts
-@opindex (fvtv-counts)
+@opindex fvtv-counts
This is a debugging flag. When used in conjunction with
@option{-fvtable-verify=std} or @option{-fvtable-verify=preinit}, this
causes the compiler to keep track of the total number of virtual calls
-Wmaybe-uninitialized @gol
-Wmissing-braces @r{(only for C/ObjC)} @gol
-Wnonnull @gol
+-Wopenmp-simd @gol
-Wparentheses @gol
-Wpointer-sign @gol
-Wreorder @gol
@table @gcctabopt
@item -Wformat=1
@itemx -Wformat
+@opindex Wformat
+@opindex Wformat=1
Option @option{-Wformat} is equivalent to @option{-Wformat=1}, and
@option{-Wno-format} is equivalent to @option{-Wformat=0}. Since
@option{-Wformat} also checks for null format arguments for several
@item -Wformat=2
+@opindex Wformat=2
Enable @option{-Wformat} plus additional format checks. Currently
equivalent to @option{-Wformat -Wformat-nonliteral -Wformat-security
-Wformat-y2k}.
@opindex Woverflow
Do not warn about compile-time overflow in constant expressions.
+@item -Wopenmp-simd
+@opindex Wopenm-simd
+Warn if the vectorizer cost model overrides the OpenMP or the Cilk Plus
+simd directive set by user. The @option{-fsimd-cost-model=unlimited} can
+be used to relax the cost model.
+
@item -Woverride-init @r{(C and Objective-C only)}
@opindex Woverride-init
@opindex Wno-override-init
@option{-fcompare-debug}.
@item -fsanitize=address
+@opindex fsanitize=address
Enable AddressSanitizer, a fast memory error detector.
Memory access instructions will be instrumented to detect
out-of-bounds and use-after-free bugs.
-See @uref{http://code.google.com/p/address-sanitizer/} for more details.
+See @uref{http://code.google.com/p/address-sanitizer/} for
+more details. The run-time behavior can be influenced using the
+@env{ASAN_OPTIONS} environment variable; see
+@url{https://code.google.com/p/address-sanitizer/wiki/Flags#Run-time_flags} for
+a list of supported options.
@item -fsanitize=thread
+@opindex fsanitize=thread
Enable ThreadSanitizer, a fast data race detector.
Memory access instructions will be instrumented to detect
-data race bugs.
-See @uref{http://code.google.com/p/data-race-test/wiki/ThreadSanitizer} for more details.
+data race bugs. See @uref{http://code.google.com/p/thread-sanitizer/} for more
+details. The run-time behavior can be influenced using the @env{TSAN_OPTIONS}
+environment variable; see
+@url{https://code.google.com/p/thread-sanitizer/wiki/Flags} for a list of
+supported options.
+
+@item -fsanitize=leak
+@opindex fsanitize=leak
+Enable LeakSanitizer, a memory leak detector.
+This option only matters for linking of executables and if neither
+@option{-fsanitize=address} nor @option{-fsanitize=thread} is used. In that
+case it will link the executable against a library that overrides @code{malloc}
+and other allocator functions. See
+@uref{https://code.google.com/p/address-sanitizer/wiki/LeakSanitizer} for more
+details. The run-time behavior can be influenced using the
+@env{LSAN_OPTIONS} environment variable.
@item -fsanitize=undefined
+@opindex fsanitize=undefined
Enable UndefinedBehaviorSanitizer, a fast undefined behavior detector.
Various computations will be instrumented to detect undefined behavior
at runtime. Current suboptions are:
-@itemize @bullet
+@table @gcctabopt
-@item @option{-fsanitize=shift}
+@item -fsanitize=shift
+@opindex fsanitize=shift
This option enables checking that the result of a shift operation is
not undefined. Note that what exactly is considered undefined differs
slightly between C and C++, as well as between ISO C90 and C99, etc.
-@item @option{-fsanitize=integer-divide-by-zero}
+@item -fsanitize=integer-divide-by-zero
+@opindex fsanitize=integer-divide-by-zero
Detect integer division by zero as well as @code{INT_MIN / -1} division.
-@item @option{-fsanitize=unreachable}
+@item -fsanitize=unreachable
+@opindex fsanitize=unreachable
With this option, the compiler will turn the @code{__builtin_unreachable}
call into a diagnostics message call instead. When reaching the
@code{__builtin_unreachable} call, the behavior is undefined.
-@item @option{-fsanitize=vla-bound}
+@item -fsanitize=vla-bound
+@opindex fsanitize=vla-bound
This option instructs the compiler to check that the size of a variable
length array is positive. This option does not have any effect in
@option{-std=c++1y} mode, as the standard requires the exception be thrown
instead.
-@item @option{-fsanitize=null}
+@item -fsanitize=null
+@opindex fsanitize=null
This option enables pointer checking. Particularly, the application
built with this option turned on will issue an error message when it
tries to dereference a NULL pointer, or if a reference (possibly an
rvalue reference) is bound to a NULL pointer.
-@end itemize
+@item -fsanitize=return
+@opindex fsanitize=return
+
+This option enables return statement checking. Programs
+built with this option turned on will issue an error message
+when the end of a non-void function is reached without actually
+returning a value. This option works in C++ only.
+
+@end table
While @option{-ftrapv} causes traps for signed overflows to be emitted,
@option{-fsanitize=undefined} gives a diagnostic message.
generating DWARF 2 debugging information with @option{-gdwarf-2}.
@item -femit-struct-debug-baseonly
+@opindex femit-struct-debug-baseonly
Emit debug information for struct-like types
only when the base name of the compilation source file
matches the base name of file in which the struct is defined.
This option works only with DWARF 2.
@item -femit-struct-debug-reduced
+@opindex femit-struct-debug-reduced
Emit debug information for struct-like types
only when the base name of the compilation source file
matches the base name of file in which the type is defined,
@itemx -fdump-rtl-@var{pass}
@itemx -fdump-rtl-@var{pass}=@var{filename}
@opindex d
+@opindex fdump-rtl-@var{pass}
Says to make debugging dumps during compilation at times specified by
@var{letters}. This is used for debugging the RTL-based passes of the
compiler. The file names for most of the dumps are made by appending
is enabled by default at @option{-O} and higher.
@item -ftree-coalesce-inlined-vars
+@opindex ftree-coalesce-inlined-vars
Tell the copyrename pass (see @option{-ftree-copyrename}) to attempt to
combine small user-defined variables too, but only if they were inlined
from other functions. It is a more limited form of
default in GCC versions older than 4.7.
@item -ftree-coalesce-vars
+@opindex ftree-coalesce-vars
Tell the copyrename pass (see @option{-ftree-copyrename}) to attempt to
combine small user-defined variables too, instead of just compiler
temporaries. This may severely limit the ability to debug an optimized
The default cost model depends on other optimization flags and is
either @code{dynamic} or @code{cheap}.
+@item -fsimd-cost-model=@var{model}
+@opindex fsimd-cost-model
+Alter the cost model used for vectorization of loops marked with the OpenMP
+or Cilk Plus simd directive. The @var{model} argument should be one of
+@code{unlimited}, @code{dynamic}, @code{cheap}. All values of @var{model}
+have the same meaning as described in @option{-fvect-cost-model} and by
+default a cost model defined with @option{-fvect-cost-model} is used.
+
@item -ftree-vrp
@opindex ftree-vrp
Perform Value Range Propagation on trees. This is similar to the
Enabled at levels @option{-O}, @option{-O2}, @option{-O3}, @option{-Os}.
@item -fuse-ld=bfd
+@opindex fuse-ld=bfd
Use the @command{bfd} linker instead of the default linker.
@item -fuse-ld=gold
+@opindex fuse-ld=gold
Use the @command{gold} linker instead of the default linker.
@item -fcprop-registers
@file{libgcc}.
@item -static-libasan
+@opindex static-libasan
When the @option{-fsanitize=address} option is used to link a program,
the GCC driver automatically links against @option{libasan}. If
@file{libasan} is available as a shared library, and the @option{-static}
other libraries statically.
@item -static-libtsan
+@opindex static-libtsan
When the @option{-fsanitize=thread} option is used to link a program,
the GCC driver automatically links against @option{libtsan}. If
@file{libtsan} is available as a shared library, and the @option{-static}
driver to link @file{libtsan} statically, without necessarily linking
other libraries statically.
+@item -static-liblsan
+@opindex static-liblsan
+When the @option{-fsanitize=leak} option is used to link a program,
+the GCC driver automatically links against @option{liblsan}. If
+@file{liblsan} is available as a shared library, and the @option{-static}
+option is not used, then this links against the shared version of
+@file{liblsan}. The @option{-static-liblsan} option directs the GCC
+driver to link @file{liblsan} statically, without necessarily linking
+other libraries statically.
+
@item -static-libubsan
+@opindex static-libubsan
When the @option{-fsanitize=undefined} option is used to link a program,
the GCC driver automatically links against @option{libubsan}. If
@file{libubsan} is available as a shared library, and the @option{-static}
other libraries statically.
@item -static-libstdc++
+@opindex static-libstdc++
When the @command{g++} program is used to link a C++ program, it
normally automatically links against @option{libstdc++}. If
@file{libstdc++} is available as a shared library, and the
use the @option{-nostdinc} and/or @option{-isystem} options.
@item -iplugindir=@var{dir}
+@opindex iplugindir=
Set the directory to search for plugins that are passed
by @option{-fplugin=@var{name}} instead of
@option{-fplugin=@var{path}/@var{name}.so}. This option is not meant
This is the default.
@item -msize-level=@var{level}
-@ opindex msize-level
+@opindex msize-level
Fine-tune size optimization with regards to instruction lengths and alignment.
The recognized values for @var{level} are:
@table @samp
@item -mpic-register=@var{reg}
@opindex mpic-register
-Specify the register to be used for PIC addressing. The default is R10
-unless stack-checking is enabled, when R9 is used.
+Specify the register to be used for PIC addressing.
+For standard PIC base case, the default will be any suitable register
+determined by compiler. For single PIC base case, the default is
+@samp{R9} if target is EABI based or stack-checking is enabled,
+otherwise the default is @samp{R10}.
@item -mpic-data-is-text-relative
@opindex mpic-data-is-text-relative
disabled by default since the cost of moving data from core registers
to Neon is high.
+@item -mslow-flash-data
+@opindex mslow-flash-data
+Assume loading data from flash is slower than fetching instruction.
+Therefore literal load is minimized for better performance.
+This option is only supported when compiling for ARMv7 M-profile and
+off by default.
+
@item -mrestrict-it
@opindex mrestrict-it
Restricts generation of IT blocks to conform to the rules of ARMv8.
@item slm
Intel Silvermont CPU with 64-bit extensions, MOVBE, MMX, SSE, SSE2, SSE3, SSSE3,
-SSE4.1, SSE4.2 and POPCNT instruction set support.
+SSE4.1, SSE4.2, POPCNT, AES, PCLMUL and RDRND instruction set support.
@item k6
AMD K6 CPU with MMX instruction set support.
@itemx -mrtm
@itemx -mtbm
@itemx -mno-tbm
-@itemx -mmpx
-@itemx -mno-mpx
@opindex mmmx
@opindex mno-mmx
@opindex msse
These switches enable or disable the use of instructions in the MMX, SSE,
SSE2, SSE3, SSSE3, SSE4.1, AVX, AVX2, AVX512F, AVX512PF, AVX512ER, AVX512CD,
AES, PCLMUL, FSGSBASE, RDRND, F16C, FMA, SSE4A, FMA4, XOP, LWP, ABM, BMI, BMI2,
-FXSR, XSAVE, XSAVEOPT, LZCNT, RTM, MPX or 3DNow!@:
+FXSR, XSAVE, XSAVEOPT, LZCNT, RTM or 3DNow!@:
extended instruction sets.
These extensions are also available as built-in functions: see
@ref{X86 Built-in Functions}, for details of the functions enabled and
values. The integer values are in @code{QImode}, @code{HImode},
@code{SImode}, @code{DImode}, @code{TImode}, and @code{OImode},
respectively.
-
-@findex BND32mode
-@findex BND64mode
-@item BND32mode BND64mode
-These modes stand for bounds for pointer of 32 and 64 bit size respectively.
-Mode size is double pointer mode size.
@end table
The machine description defines @code{Pmode} as a C macro which expands
@xref{Jump Patterns},
also see @ref{Condition Code}.
-@findex MODE_POINTER_BOUNDS
-@item MODE_POINTER_BOUNDS
-Pointer bounds modes. Used to represent values of pointer bounds type.
-Operations in these modes may be executed as NOPs depending on hardware
-features and environment setup.
-
@findex MODE_RANDOM
@item MODE_RANDOM
This is a catchall mode class for modes which don't fit into the above
@option{-pedantic} to receive all required diagnostics).
A new edition of the ISO C standard was published in 1999 as ISO/IEC
-9899:1999, and is commonly known as @dfn{C99}. GCC has incomplete
-support for this standard version; see
+9899:1999, and is commonly known as @dfn{C99}. GCC has substantially
+complete support for this standard version; see
@uref{http://gcc.gnu.org/c99status.html} for details. To select this
standard, use @option{-std=c99} or @option{-std=iso9899:1999}. (While in
development, drafts of this standard version were referred to as
uncorrected version.
A fourth version of the C standard, known as @dfn{C11}, was published
-in 2011 as ISO/IEC 9899:2011. GCC has limited incomplete support for
-parts of this standard, enabled with @option{-std=c11} or
+in 2011 as ISO/IEC 9899:2011. GCC has substantially complete support
+for this standard, enabled with @option{-std=c11} or
@option{-std=iso9899:2011}. (While in development, drafts of this
standard version were referred to as @dfn{C1X}.)
@option{-std=gnu90} (for C90 with GNU extensions), @option{-std=gnu99}
(for C99 with GNU extensions) or @option{-std=gnu11} (for C11 with GNU
extensions). The default, if no C language dialect
-options are given, is @option{-std=gnu90}; this will change to
-@option{-std=gnu99} or @option{-std=gnu11} in some future release when
-the C99 or C11 support is
-complete. Some features that are part of the C99 standard are
+options are given, is @option{-std=gnu90}; this is intended to change
+to @option{-std=gnu11} in some future release. Some features that are
+part of the C99 standard are
accepted as extensions in C90 mode, and some features that are part of
the C11 standard are accepted as extensions in C90 and C99 modes.
GCC does not provide the library facilities required only of hosted
implementations, nor yet all the facilities required by C99 of
-freestanding implementations; to use the facilities of a hosted
+freestanding implementations on all platforms; to use the facilities of a hosted
environment, you will need to find them elsewhere (for example, in the
GNU C library). @xref{Standard Libraries,,Standard Libraries}.
The default version of this hook returns @code{va_list_type_node}.
@end deftypefn
-@deftypefn {Target Hook} tree TARGET_FN_ABI_VA_LIST_BOUNDS_SIZE (tree @var{fndecl})
-This hook returns size for @code{va_list} object in function specified
-by @var{fndecl}. This hook is used by Pointer Bounds Checker to build bounds
-for @code{va_list} object. Return @code{integer_zero_node} if no bounds
-should be used (e.g. @code{va_list} is a scalar pointer to the stack).
-@end deftypefn
-
@deftypefn {Target Hook} tree TARGET_CANONICAL_VA_LIST_TYPE (tree @var{type})
This hook returns the va_list type of the calling convention specified by the
type of @var{type}. If @var{type} is not a valid va_list type, it returns
Otherwise, you should not define this hook.
@end deftypefn
-@deftypefn {Target Hook} rtx TARGET_LOAD_BOUNDS_FOR_ARG (rtx @var{slot}, rtx @var{arg}, rtx @var{slot_no})
-This hook is used by expand pass to emit insn to load bounds of
-@var{arg} passed in @var{slot}. Expand pass uses this hook in case
-bounds of @var{arg} are not passed in register. If @var{slot} is a
-memory, then bounds are loaded as for regular pointer loaded from
-memory. If @var{slot} is not a memory then @var{slot_no} is an integer
-constant holding number of the target dependent special slot which
-should be used to obtain bounds. Hook returns RTX holding loaded bounds.
-@end deftypefn
-
-@deftypefn {Target Hook} void TARGET_STORE_BOUNDS_FOR_ARG (rtx @var{arg}, rtx @var{slot}, rtx @var{bounds}, rtx @var{slot_no})
-This hook is used by expand pass to emit insns to store @var{bounds} of
-@var{arg} passed in @var{slot}. Expand pass uses this hook in case
-@var{bounds} of @var{arg} are not passed in register. If @var{slot} is a
-memory, then @var{bounds} are stored as for regular pointer stored in
-memory. If @var{slot} is not a memory then @var{slot_no} is an integer
-constant holding number of the target dependent special slot which
-should be used to store @var{bounds}.
-@end deftypefn
-
@node Trampolines
@section Trampolines for Nested Functions
@cindex trampolines for nested functions
in @file{libgcc.a}, you do not need to define this macro.
@end defmac
+@defmac TARGET_HAS_NO_HW_DIVIDE
+This macro should be defined if the target has no hardware divide
+instructions. If this macro is defined, GCC will use an algorithm which
+make use of simple logical and arithmetic operations for 64-bit
+division. If the macro is not defined, GCC will use an algorithm which
+make use of a 64-bit by 32-bit divide primitive.
+@end defmac
+
@cindex @code{EDOM}, implicit usage
@findex matherr
@defmac TARGET_EDOM
loads.
@end deftypefn
+@deftypefn {Target Hook} int TARGET_SIMD_CLONE_COMPUTE_VECSIZE_AND_SIMDLEN (struct cgraph_node *@var{}, struct cgraph_simd_clone *@var{}, @var{tree}, @var{int})
+This hook should set @var{vecsize_mangle}, @var{vecsize_int}, @var{vecsize_float}
+fields in @var{simd_clone} structure pointed by @var{clone_info} argument and also
+@var{simdlen} field if it was previously 0.
+The hook should return 0 if SIMD clones shouldn't be emitted,
+or number of @var{vecsize_mangle} variants that should be emitted.
+@end deftypefn
+
+@deftypefn {Target Hook} void TARGET_SIMD_CLONE_ADJUST (struct cgraph_node *@var{})
+This hook should add implicit @code{attribute(target("..."))} attribute
+to SIMD clone @var{node} if needed.
+@end deftypefn
+
+@deftypefn {Target Hook} int TARGET_SIMD_CLONE_USABLE (struct cgraph_node *@var{})
+This hook should return -1 if SIMD clone @var{node} shouldn't be used
+in vectorized loops in current function, or non-negative number if it is
+usable. In that case, the smaller the number is, the more desirable it is
+to use it.
+@end deftypefn
+
@node Anchored Addresses
@section Anchored Addresses
@cindex anchored addresses
built-in function.
@end deftypefn
-@deftypefn {Target Hook} tree TARGET_BUILTIN_CHKP_FUNCTION (unsigned @var{fcode})
-This hook allows target to redefine built-in functions used by
-Pointer Bounds Checker for code instrumentation. Hook should return
-fndecl of function implementing generic builtin whose code is
-passed in @var{fcode}. Currently following built-in functions are
-obtained using this hook:
-@deftypefn {Built-in Function} bnd __chkp_bndmk (const void *@var{lb}, size_t @var{size})
-Function code - BUILT_IN_CHKP_BNDMK. This built-in function is used
-by Pointer Bounds Checker to create bound values. @var{lb} holds low
-bound of the resulting bounds. @var{size} holds size of created bounds.
-@end deftypefn
-
-@deftypefn {Built-in Function} void __chkp_bndstx (const void **@var{loc}, const void *@var{ptr}, bnd @var{b})
-Function code - @code{BUILT_IN_CHKP_BNDSTX}. This built-in function is used
-by Pointer Bounds Checker to store bounds @var{b} for pointer @var{ptr}
-stored by address @var{loc}.
-@end deftypefn
-
-@deftypefn {Built-in Function} bnd __chkp_bndldx (const void **@var{loc}, const void *@var{ptr})
-Function code - @code{BUILT_IN_CHKP_BNDLDX}. This built-in function is used
-by Pointer Bounds Checker to get bounds of pointer @var{ptr} loaded by
-address @var{loc}.
-@end deftypefn
-
-@deftypefn {Built-in Function} void __chkp_bndcl (bnd @var{b}, const void *@var{ptr})
-Function code - @code{BUILT_IN_CHKP_BNDCL}. This built-in function is used
-by Pointer Bounds Checker to perform check for pointer @var{ptr} against
-lower bound of bounds @var{b}.
-@end deftypefn
-
-@deftypefn {Built-in Function} void __chkp_bndcu (bnd @var{b}, const void *@var{ptr})
-Function code - @code{BUILT_IN_CHKP_BNDCU}. This built-in function is used
-by Pointer Bounds Checker to perform check for pointer @var{ptr} against
-upper bound of bounds @var{b}.
-@end deftypefn
-
-@deftypefn {Built-in Function} bnd __chkp_bndret (void *@var{ptr})
-Function code - @code{BUILT_IN_CHKP_BNDRET}. This built-in function is used
-by Pointer Bounds Checker to obtain bounds returned by call statement.
-@var{ptr} passed to buil-in is @code{SSA_NAME} returned by call.
-@end deftypefn
-
-@deftypefn {Built-in Function} bnd __chkp_arg_bnd (void *@var{arg})
-Function code - @code{BUILT_IN_CHKP_ARG_BND}. This built-in function is
-used by Pointer Bounds Checker to obtain bounds passed for input argument.
-@var{arg} is default @code{SSA_NAME} of the @code{PARM_DECL} whose
-bounds we want to obtain.
-@end deftypefn
-
-@deftypefn {Built-in Function} bnd __chkp_intersect (bnd @var{b1}, bnd @var{b2})
-Function code - @code{BUILT_IN_CHKP_INTERSECT}. This built-in function
-returns intersection of bounds @var{b1} and @var{b2}.
-@end deftypefn
-
-@deftypefn {Built-in Function} bnd __chkp_narrow (const void *@var{ptr}, bnd @var{b}, size_t @var{s})
-Function code - @code{BUILT_IN_CHKP_NARROW}. This built-in function
-returns intersection of bounds @var{b} and
-[@var{ptr}, @var{ptr} + @var{s} - @code{1}].
-@end deftypefn
-
-@deftypefn {Built-in Function} void *__chkp_set_bounds (const void *@var{ptr}, size_t @var{s})
-Function code - @code{BUILT_IN_CHKP_SET_PTR_BOUNDS}. This built-in function
-returns @var{ptr} with bounds [@var{ptr}, @var{ptr} + @var{s} - @code{1}].
-@end deftypefn
-
-@deftypefn {Built-in Function} size_t __chkp_sizeof (const void *@var{ptr})
-Function code - @code{BUILT_IN_CHKP_SIZEOF}. This built-in function
-returns size of object referenced by @var{ptr}. @var{ptr} is always
-@code{ADDR_EXPR} of @code{VAR_DECL}. This built-in is used by
-Pointer Boudns Checker when bounds of object cannot be computed statically
-(e.g. object has incomplete type).
-@end deftypefn
-
-@deftypefn {Built-in Function} const void *__chkp_extract_lower (bnd @var{b})
-Function code - @code{BUILT_IN_CHKP_EXTRACT_LOWER}. This built-in function
-returns lower bound of bounds @var{b}.
-@end deftypefn
-
-@deftypefn {Built-in Function} const void *__chkp_extract_upper (bnd @var{b})
-Function code - @code{BUILT_IN_CHKP_EXTRACT_UPPER}. This built-in function
-returns upper bound of bounds @var{b}.
-@end deftypefn
-@end deftypefn
-@deftypefn {Target Hook} tree TARGET_CHKP_BOUND_TYPE (void)
-Return type to be used for bounds
-@end deftypefn
-@deftypefn {Target Hook} {enum machine_mode} TARGET_CHKP_BOUND_MODE (void)
-Return mode to be used for bounds.
-@end deftypefn
-
@deftypefn {Target Hook} tree TARGET_RESOLVE_OVERLOADED_BUILTIN (unsigned int @var{loc}, tree @var{fndecl}, void *@var{arglist})
Select a replacement for a machine specific built-in function that
was set up by @samp{TARGET_INIT_BUILTINS}. This is done
The default value of this hook is based on target's libc.
@end deftypefn
+@deftypefn {Target Hook} {unsigned int} TARGET_ATOMIC_ALIGN_FOR_MODE (enum machine_mode @var{mode})
+If defined, this function returns an appropriate alignment in bits for an atomic object of machine_mode @var{mode}. If 0 is returned then the default alignment for the specified mode is used.
+@end deftypefn
+
@deftypefn {Target Hook} void TARGET_ATOMIC_ASSIGN_EXPAND_FENV (tree *@var{hold}, tree *@var{clear}, tree *@var{update})
ISO C11 requires atomic compound assignments that may raise floating-point exceptions to raise exceptions corresponding to the arithmetic operation whose result was successfully stored in a compare-and-exchange sequence. This requires code equivalent to calls to @code{feholdexcept}, @code{feclearexcept} and @code{feupdateenv} to be generated at appropriate points in the compare-and-exchange sequence. This hook should set @code{*@var{hold}} to an expression equivalent to the call to @code{feholdexcept}, @code{*@var{clear}} to an expression equivalent to the call to @code{feclearexcept} and @code{*@var{update}} to an expression equivalent to the call to @code{feupdateenv}. The three expressions are @code{NULL_TREE} on entry to the hook and may be left as @code{NULL_TREE} if no code is required in a particular place. The default implementation leaves all three expressions as @code{NULL_TREE}. The @code{__atomic_feraiseexcept} function from @code{libatomic} may be of use as part of the code generated in @code{*@var{update}}.
@end deftypefn
@hook TARGET_FN_ABI_VA_LIST
-@hook TARGET_FN_ABI_VA_LIST_BOUNDS_SIZE
-
@hook TARGET_CANONICAL_VA_LIST_TYPE
@hook TARGET_GIMPLIFY_VA_ARG_EXPR
@hook TARGET_PRETEND_OUTGOING_VARARGS_NAMED
-@hook TARGET_LOAD_BOUNDS_FOR_ARG
-
-@hook TARGET_STORE_BOUNDS_FOR_ARG
-
@node Trampolines
@section Trampolines for Nested Functions
@cindex trampolines for nested functions
in @file{libgcc.a}, you do not need to define this macro.
@end defmac
+@defmac TARGET_HAS_NO_HW_DIVIDE
+This macro should be defined if the target has no hardware divide
+instructions. If this macro is defined, GCC will use an algorithm which
+make use of simple logical and arithmetic operations for 64-bit
+division. If the macro is not defined, GCC will use an algorithm which
+make use of a 64-bit by 32-bit divide primitive.
+@end defmac
+
@cindex @code{EDOM}, implicit usage
@findex matherr
@defmac TARGET_EDOM
@hook TARGET_VECTORIZE_BUILTIN_GATHER
+@hook TARGET_SIMD_CLONE_COMPUTE_VECSIZE_AND_SIMDLEN
+
+@hook TARGET_SIMD_CLONE_ADJUST
+
+@hook TARGET_SIMD_CLONE_USABLE
+
@node Anchored Addresses
@section Anchored Addresses
@cindex anchored addresses
@hook TARGET_EXPAND_BUILTIN
-@hook TARGET_BUILTIN_CHKP_FUNCTION
-@hook TARGET_CHKP_BOUND_TYPE
-@hook TARGET_CHKP_BOUND_MODE
-
@hook TARGET_RESOLVE_OVERLOADED_BUILTIN
@hook TARGET_FOLD_BUILTIN
@hook TARGET_HAS_IFUNC_P
+@hook TARGET_ATOMIC_ALIGN_FOR_MODE
+
@hook TARGET_ATOMIC_ASSIGN_EXPAND_FENV
@defmac TARGET_SUPPORTS_WIDE_INT
pending_stack_adjust = 0;
}
}
+
+/* Remember pending_stack_adjust/stack_pointer_delta.
+ To be used around code that may call do_pending_stack_adjust (),
+ but the generated code could be discarded e.g. using delete_insns_since. */
+
+void
+save_pending_stack_adjust (saved_pending_stack_adjust *save)
+{
+ save->x_pending_stack_adjust = pending_stack_adjust;
+ save->x_stack_pointer_delta = stack_pointer_delta;
+}
+
+/* Restore the saved pending_stack_adjust/stack_pointer_delta. */
+
+void
+restore_pending_stack_adjust (saved_pending_stack_adjust *save)
+{
+ if (inhibit_defer_pop == 0)
+ {
+ pending_stack_adjust = save->x_pending_stack_adjust;
+ stack_pointer_delta = save->x_stack_pointer_delta;
+ }
+}
\f
/* Expand conditional expressions. */
#include "dbgcnt.h"
#include "target.h"
#include "params.h"
+#include "pointer-set.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-ssa.h"
static inline unsigned
dwf_regno (const_rtx reg)
{
+ gcc_assert (REGNO (reg) < FIRST_PSEUDO_REGISTER);
return DWARF_FRAME_REGNUM (REGNO (reg));
}
#include "varasm.h"
#include "function.h"
#include "emit-rtl.h"
-#include "gimple.h"
+#include "hash-table.h"
#include "version.h"
#include "flags.h"
#include "hard-reg-set.h"
#include "dwarf2out.h"
#include "dwarf2asm.h"
#include "toplev.h"
-#include "ggc.h"
#include "md5.h"
#include "tm_p.h"
#include "diagnostic.h"
#include "target.h"
#include "common/common-target.h"
#include "langhooks.h"
-#include "hash-table.h"
#include "cgraph.h"
#include "input.h"
#include "ira.h"
if (type_node != NULL)
die_offset = (type_node->skeleton_die != NULL
? type_node->skeleton_die->die_offset
- : 0);
+ : comp_unit_die ()->die_offset);
}
output_pubname (die_offset, pub);
gen_formal_parameter_pack_die (generic_decl_parm,
parm, subr_die,
&parm);
- else if (parm && !POINTER_BOUNDS_P (parm))
+ else if (parm)
{
dw_die_ref parm_die = gen_decl_die (parm, NULL, subr_die);
parm = DECL_CHAIN (parm);
}
- else if (parm)
- parm = DECL_CHAIN (parm);
if (generic_decl_parm)
generic_decl_parm = DECL_CHAIN (generic_decl_parm);
case FIXED_POINT_TYPE:
case COMPLEX_TYPE:
case BOOLEAN_TYPE:
- case POINTER_BOUNDS_TYPE:
/* No DIEs needed for fundamental types. */
break;
declarations, file-scope (extern) function declarations (which
had no corresponding body) and file-scope tagged type declarations
and definitions which have not yet been forced out. */
- if ((TREE_CODE (decl) != FUNCTION_DECL || !DECL_INITIAL (decl))
- && !POINTER_BOUNDS_P (decl))
+ if (TREE_CODE (decl) != FUNCTION_DECL || !DECL_INITIAL (decl))
dwarf2out_decl (decl);
}
#include "rtl.h"
#include "tree.h"
#include "varasm.h"
-#include "gimple.h"
+#include "basic-block.h"
+#include "tree-eh.h"
#include "tm_p.h"
#include "flags.h"
#include "function.h"
#include "insn-config.h"
#include "recog.h"
#include "bitmap.h"
-#include "basic-block.h"
-#include "ggc.h"
#include "debug.h"
#include "langhooks.h"
#include "df.h"
#include "params.h"
#include "target.h"
-#include "tree-eh.h"
struct target_rtl default_target_rtl;
#if SWITCHABLE_TARGET
#include "insn-config.h"
#include "except.h"
#include "hard-reg-set.h"
-#include "basic-block.h"
#include "output.h"
#include "dwarf2asm.h"
#include "dwarf2out.h"
#include "toplev.h"
#include "hash-table.h"
#include "intl.h"
-#include "ggc.h"
#include "tm_p.h"
#include "target.h"
#include "common/common-target.h"
#include "diagnostic.h"
#include "tree-pretty-print.h"
#include "tree-pass.h"
-#include "gimple.h"
+#include "pointer-set.h"
#include "cfgloop.h"
/* Provide defaults for stuff that may not be defined when using
ORIGINAL_AS_FOR_TARGET="@ORIGINAL_AS_FOR_TARGET@"
ORIGINAL_LD_FOR_TARGET="@ORIGINAL_LD_FOR_TARGET@"
+ORIGINAL_LD_BFD_FOR_TARGET="@ORIGINAL_LD_BFD_FOR_TARGET@"
+ORIGINAL_LD_GOLD_FOR_TARGET="@ORIGINAL_LD_GOLD_FOR_TARGET@"
ORIGINAL_PLUGIN_LD_FOR_TARGET="@ORIGINAL_PLUGIN_LD_FOR_TARGET@"
ORIGINAL_NM_FOR_TARGET="@ORIGINAL_NM_FOR_TARGET@"
exeext=@host_exeext@
dir=gas
;;
collect-ld)
- # when using a linker plugin, gcc will always pass '-plugin' as the
- # first or second option to the linker.
- if test x"$1" = "x-plugin" || test x"$2" = "x-plugin"; then
- original=$ORIGINAL_PLUGIN_LD_FOR_TARGET
+ # Check -fuse-ld=bfd and -fuse-ld=gold
+ case " $* " in
+ *\ -fuse-ld=bfd\ *)
+ original=$ORIGINAL_LD_BFD_FOR_TARGET
+ ;;
+ *\ -fuse-ld=gold\ *)
+ original=$ORIGINAL_LD_GOLD_FOR_TARGET
+ ;;
+ *)
+ # when using a linker plugin, gcc will always pass '-plugin' as the
+ # first or second option to the linker.
+ if test x"$1" = "x-plugin" || test x"$2" = "x-plugin"; then
+ original=$ORIGINAL_PLUGIN_LD_FOR_TARGET
+ else
+ original=$ORIGINAL_LD_FOR_TARGET
+ fi
+ ;;
+ esac
+ prog=ld-new$exeext
+ if test "$original" = ../gold/ld-new$exeext; then
+ dir=gold
+ # No need to handle relink since gold doesn't use libtool.
+ fast_install=yes
else
- original=$ORIGINAL_LD_FOR_TARGET
+ dir=ld
fi
- prog=ld-new$exeext
- dir=ld
id=ld
;;
nm)
{
rtx temp2;
- /* ??? emit_conditional_move forces a stack adjustment via
- compare_from_rtx so, if the sequence is discarded, it will
- be lost. Do it now instead. */
- do_pending_stack_adjust ();
-
start_sequence ();
temp2 = copy_to_mode_reg (mode, op0);
temp = expand_binop (mode, add_optab, temp2, gen_int_mode (d - 1, mode),
#include "intl.h"
#include "tm_p.h"
#include "tree-iterator.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-ssa.h"
#include "cgraph.h"
HOST_WIDE_INT bytepos = INTVAL (XEXP (XVECEXP (src, 0, i), 1));
enum machine_mode mode = GET_MODE (tmps[i]);
unsigned int bytelen = GET_MODE_SIZE (mode);
- unsigned int adj_bytelen = bytelen;
+ unsigned int adj_bytelen;
rtx dest = dst;
/* Handle trailing fragments that run over the size of the struct. */
if (ssize >= 0 && bytepos + (HOST_WIDE_INT) bytelen > ssize)
adj_bytelen = ssize - bytepos;
+ else
+ adj_bytelen = bytelen;
if (GET_CODE (dst) == CONCAT)
{
}
}
+ /* Handle trailing fragments that run over the size of the struct. */
if (ssize >= 0 && bytepos + (HOST_WIDE_INT) bytelen > ssize)
{
/* store_bit_field always takes its value from the lsb.
tmps[i] = expand_shift (RSHIFT_EXPR, mode, tmps[i],
shift, tmps[i], 0);
}
- bytelen = adj_bytelen;
+
+ /* Make sure not to write past the end of the struct. */
+ store_bit_field (dest,
+ adj_bytelen * BITS_PER_UNIT, bytepos * BITS_PER_UNIT,
+ bytepos * BITS_PER_UNIT, ssize * BITS_PER_UNIT - 1,
+ VOIDmode, tmps[i]);
}
/* Optimize the access just a bit. */
- if (MEM_P (dest)
- && (! SLOW_UNALIGNED_ACCESS (mode, MEM_ALIGN (dest))
- || MEM_ALIGN (dest) >= GET_MODE_ALIGNMENT (mode))
- && bytepos * BITS_PER_UNIT % GET_MODE_ALIGNMENT (mode) == 0
- && bytelen == GET_MODE_SIZE (mode))
+ else if (MEM_P (dest)
+ && (!SLOW_UNALIGNED_ACCESS (mode, MEM_ALIGN (dest))
+ || MEM_ALIGN (dest) >= GET_MODE_ALIGNMENT (mode))
+ && bytepos * BITS_PER_UNIT % GET_MODE_ALIGNMENT (mode) == 0
+ && bytelen == GET_MODE_SIZE (mode))
emit_move_insn (adjust_address (dest, mode, bytepos), tmps[i]);
+
else
store_bit_field (dest, bytelen * BITS_PER_UNIT, bytepos * BITS_PER_UNIT,
0, 0, mode, tmps[i]);
expand_insn (icode, 2, ops);
}
else
- store_bit_field (mem, GET_MODE_BITSIZE (mode),
- 0, 0, 0, mode, reg);
+ store_bit_field (mem, GET_MODE_BITSIZE (mode), 0, 0, 0, mode, reg);
return;
}
if (TREE_CODE (to) == COMPONENT_REF
&& DECL_BIT_FIELD_TYPE (TREE_OPERAND (to, 1)))
get_bit_range (&bitregion_start, &bitregion_end, to, &bitpos, &offset);
+ /* The C++ memory model naturally applies to byte-aligned fields.
+ However, if we do not have a DECL_BIT_FIELD_TYPE but BITPOS or
+ BITSIZE are not byte-aligned, there is no need to limit the range
+ we can access. This can occur with packed structures in Ada. */
+ else if (bitsize > 0
+ && bitsize % BITS_PER_UNIT == 0
+ && bitpos % BITS_PER_UNIT == 0)
+ {
+ bitregion_start = bitpos;
+ bitregion_end = bitpos + bitsize - 1;
+ }
to_rtx = expand_expr (tem, NULL_RTX, VOIDmode, EXPAND_WRITE);
{
rtx insn;
- /* ??? Same problem as in expmed.c: emit_conditional_move
- forces a stack adjustment via compare_from_rtx, and we
- lose the stack adjustment if the sequence we are about
- to create is discarded. */
- do_pending_stack_adjust ();
-
start_sequence ();
/* Try to emit the conditional move. */
/* Pop any previously-pushed arguments that have not been popped yet. */
extern void do_pending_stack_adjust (void);
+/* Struct for saving/restoring of pending_stack_adjust/stack_pointer_delta
+ values. */
+
+struct saved_pending_stack_adjust
+{
+ /* Saved value of pending_stack_adjust. */
+ int x_pending_stack_adjust;
+
+ /* Saved value of stack_pointer_delta. */
+ int x_stack_pointer_delta;
+};
+
+/* Remember pending_stack_adjust/stack_pointer_delta.
+ To be used around code that may call do_pending_stack_adjust (),
+ but the generated code could be discarded e.g. using delete_insns_since. */
+
+extern void save_pending_stack_adjust (saved_pending_stack_adjust *);
+
+/* Restore the saved pending_stack_adjust/stack_pointer_delta. */
+
+extern void restore_pending_stack_adjust (saved_pending_stack_adjust *);
+
/* Return the tree node and offset if a given argument corresponds to
a string constant. */
extern tree string_constant (tree, tree *);
SANITIZE_ADDRESS = 1 << 0,
/* ThreadSanitizer. */
SANITIZE_THREAD = 1 << 1,
+ /* LeakSanitizer. */
+ SANITIZE_LEAK = 1 << 2,
/* UndefinedBehaviorSanitizer. */
- SANITIZE_SHIFT = 1 << 2,
- SANITIZE_DIVIDE = 1 << 3,
- SANITIZE_UNREACHABLE = 1 << 4,
- SANITIZE_VLA = 1 << 5,
- SANITIZE_NULL = 1 << 6,
+ SANITIZE_SHIFT = 1 << 3,
+ SANITIZE_DIVIDE = 1 << 4,
+ SANITIZE_UNREACHABLE = 1 << 5,
+ SANITIZE_VLA = 1 << 6,
+ SANITIZE_NULL = 1 << 7,
+ SANITIZE_RETURN = 1 << 8,
SANITIZE_UNDEFINED = SANITIZE_SHIFT | SANITIZE_DIVIDE | SANITIZE_UNREACHABLE
- | SANITIZE_VLA | SANITIZE_NULL
+ | SANITIZE_VLA | SANITIZE_NULL | SANITIZE_RETURN
};
/* flag_vtable_verify initialization levels. */
#include "target.h"
#include "diagnostic-core.h"
#include "intl.h"
-#include "ggc.h"
-#include "hash-table.h"
#include "langhooks.h"
#include "md5.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimplify.h"
#include "tree-dfa.h"
+#include "hash-table.h" /* Required for ENABLE_FOLD_CHECKING. */
/* Nonzero if we are folding constants inside an initializer; zero
otherwise. */
unsigned HOST_WIDE_INT indexi = offset * BITS_PER_UNIT;
tree index = bitsize_int (indexi);
- if (offset/part_widthi <= TYPE_VECTOR_SUBPARTS (op00type))
+ if (offset / part_widthi < TYPE_VECTOR_SUBPARTS (op00type))
return fold_build3_loc (loc,
BIT_FIELD_REF, type, op00,
part_width, index);
+2013-12-01 Paul Thomas <pault@gcc.gnu.org>
+
+ PR fortran/57354
+ * trans-array.c (gfc_conv_resolve_dependencies): For other than
+ SS_SECTION, do a dependency check if the lhs is liable to be
+ reallocated.
+
+2013-12-01 Paul Thomas <pault@gcc.gnu.org>
+
+ PR fortran/58410
+ * trans-array.c (gfc_alloc_allocatable_for_assignment): Do not
+ use the array bounds of an unallocated array but set its size
+ to zero instead.
+
+2013-12-01 Paul Thomas <pault@gcc.gnu.org>
+
+ PR fortran/34547
+ * resolve.c (resolve_transfer): EXPR_NULL is always in an
+ invalid context in a transfer statement.
+
+2013-11-28 Sergey Ostanevich <sergos.gnu@gmail.com>
+
+ * lang.opt (Wopenmp-simd): New.
+
+2013-11-25 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/59143
+ * interface.c (get_expr_storage_size): Handle array-valued type-bound
+ procedures.
+
+2013-11-24 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+
+ * scanner.c (gfc_open_intrinsic_module): Remove function.
+ * gfortran.h (gfc_open_intrinsic_module): Remove prototype.
+
+2013-11-23 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/59228
+ * interface.c (compare_parameter): Check for array spec.
+
+2013-11-22 Andrew MacLeod <amacleod@redhat.com>
+
+ * trans.c: Add required include files from gimple.h.
+ * trans-expr.c: Likewise
+ * trans-openmp.c: Likewise
+
+2013-11-22 David Malcolm <dmalcolm@redhat.com>
+
+ * trans.c (trans_runtime_error_vararg): Remove use of input_line
+ macro.
+
2013-11-17 Andrew MacLeod <amacleod@redhat.com>
* fortran/trans-intrinsic.c: Include tree-nested.h.
void gfc_add_intrinsic_modules_path (const char *);
void gfc_release_include_path (void);
FILE *gfc_open_included_file (const char *, bool, bool);
-FILE *gfc_open_intrinsic_module (const char *);
int gfc_at_end (void);
int gfc_at_eof (void);
&& (actual->symtree->n.sym->attr.asynchronous
|| actual->symtree->n.sym->attr.volatile_)
&& (formal->attr.asynchronous || formal->attr.volatile_)
- && actual->rank && !gfc_is_simply_contiguous (actual, true)
+ && actual->rank && formal->as && !gfc_is_simply_contiguous (actual, true)
&& ((formal->as->type != AS_ASSUMED_SHAPE
&& formal->as->type != AS_ASSUMED_RANK && !formal->attr.pointer)
|| formal->attr.contiguous))
- mpz_get_si (ref->u.ar.as->lower[i]->value.integer));
}
}
+ else if (ref->type == REF_COMPONENT && ref->u.c.component->attr.function
+ && ref->u.c.component->attr.proc_pointer
+ && ref->u.c.component->attr.dimension)
+ {
+ /* Array-valued procedure-pointer components. */
+ gfc_array_spec *as = ref->u.c.component->as;
+ for (i = 0; i < as->rank; i++)
+ {
+ if (!as->upper[i] || !as->lower[i]
+ || as->upper[i]->expr_type != EXPR_CONSTANT
+ || as->lower[i]->expr_type != EXPR_CONSTANT)
+ return 0;
+
+ elements = elements
+ * (mpz_get_si (as->upper[i]->value.integer)
+ - mpz_get_si (as->lower[i]->value.integer) + 1L);
+ }
+ }
}
if (substrlen)
Fortran Warning
Warn on intrinsics not part of the selected standard
+Wopenmp-simd
+Fortran
+; Documented in C
+
Wreal-q-constant
Fortran Warning
Warn about real-literal-constants with 'q' exponent-letter
&& exp->value.op.op == INTRINSIC_PARENTHESES)
exp = exp->value.op.op1;
- if (exp && exp->expr_type == EXPR_NULL && exp->ts.type == BT_UNKNOWN)
+ if (exp && exp->expr_type == EXPR_NULL
+ && code->ext.dt)
{
- gfc_error ("NULL intrinsic at %L in data transfer statement requires "
- "MOLD=", &exp->where);
+ gfc_error ("Invalid context for NULL () intrinsic at %L",
+ &exp->where);
return;
}
return f;
}
-FILE *
-gfc_open_intrinsic_module (const char *name)
-{
- FILE *f = NULL;
-
- if (IS_ABSOLUTE_PATH (name))
- {
- f = gfc_open_file (name);
- if (f && gfc_cpp_makedep ())
- gfc_cpp_add_dep (name, true);
- }
-
- if (!f)
- f = open_included_file (name, intrinsic_modules_dirs, true, true);
-
- return f;
-}
-
/* Test to see if we're at the end of the main source file. */
for (ss = rss; ss != gfc_ss_terminator; ss = ss->next)
{
+ ss_expr = ss->info->expr;
+
if (ss->info->type != GFC_SS_SECTION)
- continue;
+ {
+ if (gfc_option.flag_realloc_lhs
+ && dest_expr != ss_expr
+ && gfc_is_reallocatable_lhs (dest_expr)
+ && ss_expr->rank)
+ nDepend = gfc_check_dependency (dest_expr, ss_expr, true);
- ss_expr = ss->info->expr;
+ continue;
+ }
if (dest_expr->symtree->n.sym != ss_expr->symtree->n.sym)
{
tree size1;
tree size2;
tree array1;
+ tree cond_null;
tree cond;
tree tmp;
tree tmp2;
jump_label2 = gfc_build_label_decl (NULL_TREE);
/* Allocate if data is NULL. */
- cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
+ cond_null = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
array1, build_int_cst (TREE_TYPE (array1), 0));
- tmp = build3_v (COND_EXPR, cond,
+ tmp = build3_v (COND_EXPR, cond_null,
build1_v (GOTO_EXPR, jump_label1),
build_empty_stmt (input_location));
gfc_add_expr_to_block (&fblock, tmp);
tmp = build1_v (LABEL_EXPR, jump_label1);
gfc_add_expr_to_block (&fblock, tmp);
- size1 = gfc_conv_descriptor_size (desc, expr1->rank);
+ /* If the lhs has not been allocated, its bounds will not have been
+ initialized and so its size is set to zero. */
+ size1 = gfc_create_var (gfc_array_index_type, NULL);
+ gfc_init_block (&alloc_block);
+ gfc_add_modify (&alloc_block, size1, gfc_index_zero_node);
+ gfc_init_block (&realloc_block);
+ gfc_add_modify (&realloc_block, size1,
+ gfc_conv_descriptor_size (desc, expr1->rank));
+ tmp = build3_v (COND_EXPR, cond_null,
+ gfc_finish_block (&alloc_block),
+ gfc_finish_block (&realloc_block));
+ gfc_add_expr_to_block (&fblock, tmp);
- /* Get the rhs size. Fix both sizes. */
+ /* Get the rhs size and fix it. */
if (expr2)
desc2 = rss->info->data.array.descriptor;
else
desc2 = NULL_TREE;
+
size2 = gfc_index_one_node;
for (n = 0; n < expr2->rank; n++)
{
gfc_array_index_type,
tmp, size2);
}
-
- size1 = gfc_evaluate_now (size1, &fblock);
size2 = gfc_evaluate_now (size2, &fblock);
cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
/* Only for gfc_trans_assign and gfc_trans_pointer_assign. */
#include "trans-stmt.h"
#include "dependency.h"
-#include "gimple.h"
#include "gimplify.h"
#include "wide-int.h"
#include "system.h"
#include "coretypes.h"
#include "tree.h"
-#include "gimple.h"
+#include "gimple-expr.h"
#include "gimplify.h" /* For create_tmp_var_raw. */
#include "stringpool.h"
#include "diagnostic-core.h" /* For internal_error. */
#include "coretypes.h"
#include "tree.h"
#include "gimple-expr.h" /* For create_tmp_var_raw. */
-#include "gimple.h"
#include "stringpool.h"
#include "tree-iterator.h"
#include "diagnostic-core.h" /* For internal_error. */
}
else
asprintf (&message, "In file '%s', around line %d",
- gfc_source_file, input_line + 1);
+ gfc_source_file, LOCATION_LINE (input_location) + 1);
arg = gfc_build_addr_expr (pchar_type_node,
gfc_build_localized_cstring_const (message));
#include "insn-config.h"
#include "recog.h"
#include "output.h"
-#include "basic-block.h"
#include "hashtab.h"
-#include "ggc.h"
#include "tm_p.h"
#include "langhooks.h"
#include "target.h"
#include "common/common-target.h"
-#include "gimple.h"
+#include "gimple-expr.h"
#include "gimplify.h"
#include "tree-pass.h"
#include "predict.h"
cl_optimization_restore (&global_options, TREE_OPTIMIZATION (opts));
}
- targetm.set_current_function (fndecl);
this_fn_optabs = this_target_optabs;
if (opts != optimization_default_node)
this_fn_optabs = (struct target_optabs *)
TREE_OPTIMIZATION_OPTABS (opts);
}
+
+ targetm.set_current_function (fndecl);
}
}
#define STACK_SPLIT_SPEC " %{fsplit-stack: --wrap=pthread_create}"
#ifndef LIBASAN_SPEC
-#ifdef STATIC_LIBASAN_LIBS
-#define ADD_STATIC_LIBASAN_LIBS \
- " %{static-libasan:" STATIC_LIBASAN_LIBS "}"
-#else
-#define ADD_STATIC_LIBASAN_LIBS
-#endif
+#define STATIC_LIBASAN_LIBS \
+ " %{static-libasan:%:include(libsanitizer.spec)%(link_libasan)}"
#ifdef LIBASAN_EARLY_SPEC
-#define LIBASAN_SPEC ADD_STATIC_LIBASAN_LIBS
+#define LIBASAN_SPEC STATIC_LIBASAN_LIBS
#elif defined(HAVE_LD_STATIC_DYNAMIC)
#define LIBASAN_SPEC "%{static-libasan:" LD_STATIC_OPTION \
"} -lasan %{static-libasan:" LD_DYNAMIC_OPTION "}" \
- ADD_STATIC_LIBASAN_LIBS
+ STATIC_LIBASAN_LIBS
#else
-#define LIBASAN_SPEC "-lasan" ADD_STATIC_LIBASAN_LIBS
+#define LIBASAN_SPEC "-lasan" STATIC_LIBASAN_LIBS
#endif
#endif
#endif
#ifndef LIBTSAN_SPEC
-#ifdef STATIC_LIBTSAN_LIBS
-#define ADD_STATIC_LIBTSAN_LIBS \
- " %{static-libtsan:" STATIC_LIBTSAN_LIBS "}"
-#else
-#define ADD_STATIC_LIBTSAN_LIBS
-#endif
+#define STATIC_LIBTSAN_LIBS \
+ " %{static-libtsan:%:include(libsanitizer.spec)%(link_libtsan)}"
#ifdef LIBTSAN_EARLY_SPEC
-#define LIBTSAN_SPEC ADD_STATIC_LIBTSAN_LIBS
+#define LIBTSAN_SPEC STATIC_LIBTSAN_LIBS
#elif defined(HAVE_LD_STATIC_DYNAMIC)
#define LIBTSAN_SPEC "%{static-libtsan:" LD_STATIC_OPTION \
"} -ltsan %{static-libtsan:" LD_DYNAMIC_OPTION "}" \
- ADD_STATIC_LIBTSAN_LIBS
+ STATIC_LIBTSAN_LIBS
#else
-#define LIBTSAN_SPEC "-ltsan" ADD_STATIC_LIBTSAN_LIBS
+#define LIBTSAN_SPEC "-ltsan" STATIC_LIBTSAN_LIBS
#endif
#endif
#define LIBTSAN_EARLY_SPEC ""
#endif
-#ifndef LIBUBSAN_SPEC
-#ifdef STATIC_LIBUBSAN_LIBS
-#define ADD_STATIC_LIBUBSAN_LIBS \
- " %{static-libubsan:" STATIC_LIBUBSAN_LIBS "}"
+#ifndef LIBLSAN_SPEC
+#define STATIC_LIBLSAN_LIBS \
+ " %{static-liblsan:%:include(libsanitizer.spec)%(link_liblsan)}"
+#ifdef HAVE_LD_STATIC_DYNAMIC
+#define LIBLSAN_SPEC "%{!shared:%{static-liblsan:" LD_STATIC_OPTION \
+ "} -llsan %{static-liblsan:" LD_DYNAMIC_OPTION "}" \
+ STATIC_LIBLSAN_LIBS "}"
#else
-#define ADD_STATIC_LIBUBSAN_LIBS
+#define LIBLSAN_SPEC "%{!shared:-llsan" STATIC_LIBLSAN_LIBS "}"
#endif
-#ifdef LIBUBSAN_EARLY_SPEC
-#define LIBUBSAN_SPEC ADD_STATIC_LIBUBSAN_LIBS
-#elif defined(HAVE_LD_STATIC_DYNAMIC)
+#endif
+
+#ifndef LIBUBSAN_SPEC
+#define STATIC_LIBUBSAN_LIBS \
+ " %{static-libubsan:%:include(libsanitizer.spec)%(link_libubsan)}"
+#ifdef HAVE_LD_STATIC_DYNAMIC
#define LIBUBSAN_SPEC "%{static-libubsan:" LD_STATIC_OPTION \
"} -lubsan %{static-libubsan:" LD_DYNAMIC_OPTION "}" \
- ADD_STATIC_LIBUBSAN_LIBS
+ STATIC_LIBUBSAN_LIBS
#else
-#define LIBUBSAN_SPEC "-lubsan" ADD_STATIC_LIBUBSAN_LIBS
+#define LIBUBSAN_SPEC "-lubsan" STATIC_LIBUBSAN_LIBS
#endif
#endif
-#ifndef LIBUBSAN_EARLY_SPEC
-#define LIBUBSAN_EARLY_SPEC ""
-#endif
-
/* config.h can define LIBGCC_SPEC to override how and when libgcc.a is
included. */
#ifndef LIBGCC_SPEC
#ifndef SANITIZER_EARLY_SPEC
#define SANITIZER_EARLY_SPEC "\
%{!nostdlib:%{!nodefaultlibs:%{%:sanitize(address):" LIBASAN_EARLY_SPEC "} \
- %{%:sanitize(thread):" LIBTSAN_EARLY_SPEC "} \
- %{%:sanitize(undefined):" LIBUBSAN_EARLY_SPEC "}}}"
+ %{%:sanitize(thread):" LIBTSAN_EARLY_SPEC "}}}"
#endif
/* Linker command line options for -fsanitize= late on the command line. */
%{%:sanitize(thread):%e-fsanitize=address is incompatible with -fsanitize=thread}}\
%{%:sanitize(thread):" LIBTSAN_SPEC "\
%{!pie:%{!shared:%e-fsanitize=thread linking must be done with -pie or -shared}}}\
- %{%:sanitize(undefined):" LIBUBSAN_SPEC "}}}"
+ %{%:sanitize(undefined):" LIBUBSAN_SPEC "}\
+ %{%:sanitize(leak):" LIBLSAN_SPEC "}}}"
#endif
/* This is the spec to use, once the code for creating the vtable
return (flag_sanitize & SANITIZE_THREAD) ? "" : NULL;
if (strcmp (argv[0], "undefined") == 0)
return (flag_sanitize & SANITIZE_UNDEFINED) ? "" : NULL;
-
+ if (strcmp (argv[0], "leak") == 0)
+ return ((flag_sanitize
+ & (SANITIZE_ADDRESS | SANITIZE_LEAK | SANITIZE_THREAD))
+ == SANITIZE_LEAK) ? "" : NULL;
return NULL;
}
bitmap_iterator bi;
- ira_setup_eliminable_regset (false);
+ ira_setup_eliminable_regset ();
curr_regs_live = BITMAP_ALLOC (®_obstack);
FOR_EACH_BB (bb)
{
"tree.h", "rtl.h", "wide-int.h", "function.h", "insn-config.h", "expr.h",
"hard-reg-set.h", "basic-block.h", "cselib.h", "insn-addr.h",
"optabs.h", "libfuncs.h", "debug.h", "ggc.h", "cgraph.h",
+ "pointer-set.h", "hash-table.h", "vec.h", "ggc.h", "basic-block.h",
+ "tree-ssa-alias.h", "internal-fn.h", "gimple-fold.h", "tree-eh.h",
+ "gimple-expr.h", "is-a.h",
"gimple.h", "gimple-iterator.h", "gimple-ssa.h", "tree-cfg.h",
"tree-phinodes.h", "ssa-iterators.h", "stringpool.h", "tree-ssanames.h",
"tree-ssa-loop.h", "tree-ssa-loop-ivopts.h", "tree-ssa-loop-manip.h",
return NULL;
}
+/* Machinery for avoiding duplicate tags within switch statements. */
+struct seen_tag
+{
+ const char *tag;
+ struct seen_tag *next;
+};
+
+int
+already_seen_tag (struct seen_tag *seen_tags, const char *tag)
+{
+ /* Linear search, so O(n^2), but n is currently small. */
+ while (seen_tags)
+ {
+ if (!strcmp (seen_tags->tag, tag))
+ return 1;
+ seen_tags = seen_tags->next;
+ }
+ /* Not yet seen this tag. */
+ return 0;
+}
+
+void
+mark_tag_as_seen (struct seen_tag **seen_tags, const char *tag)
+{
+ /* Add to front of linked list. */
+ struct seen_tag *new_node = XCNEW (struct seen_tag);
+ new_node->tag = tag;
+ new_node->next = *seen_tags;
+ *seen_tags = new_node;
+}
+
static void
-walk_subclasses (type_p base, struct walk_type_data *d)
+walk_subclasses (type_p base, struct walk_type_data *d,
+ struct seen_tag **seen_tags)
{
for (type_p sub = base->u.s.first_subclass; sub != NULL;
sub = sub->u.s.next_sibling_class)
{
const char *type_tag = get_string_option (sub->u.s.opt, "tag");
- if (type_tag)
+ if (type_tag && !already_seen_tag (*seen_tags, type_tag))
{
+ mark_tag_as_seen (seen_tags, type_tag);
oprintf (d->of, "%*scase %s:\n", d->indent, "", type_tag);
d->indent += 2;
oprintf (d->of, "%*s{\n", d->indent, "");
oprintf (d->of, "%*sbreak;\n", d->indent, "");
d->indent -= 2;
}
- walk_subclasses (sub, d);
+ walk_subclasses (sub, d, seen_tags);
}
}
else if (desc)
{
/* Add cases to handle subclasses. */
- walk_subclasses (t, d);
+ struct seen_tag *tags = NULL;
+ walk_subclasses (t, d, &tags);
/* Ensure that if someone forgets a "tag" option that we don't
silent fail to traverse that subclass's fields. */
break;
case MODE_INT:
- case MODE_POINTER_BOUNDS:
case MODE_FLOAT:
case MODE_DECIMAL_FLOAT:
case MODE_FRACT:
new_mode (cl, name, file, line);
}
-#define POINTER_BOUNDS_MODE(N, Y) \
- make_pointer_bounds_mode (#N, Y, __FILE__, __LINE__)
-
-static void ATTRIBUTE_UNUSED
-make_pointer_bounds_mode (const char *name,
- unsigned int bytesize,
- const char *file, unsigned int line)
-{
- struct mode_data *m = new_mode (MODE_POINTER_BOUNDS, name, file, line);
- m->bytesize = bytesize;
-}
-
-
#define INT_MODE(N, Y) FRACTIONAL_INT_MODE (N, -1U, Y)
#define FRACTIONAL_INT_MODE(N, B, Y) \
make_int_mode (#N, B, Y, __FILE__, __LINE__)
ggc_internal_cleared_alloc_stat (s PASS_MEM_STAT);
}
+static inline struct simd_clone *
+ggc_alloc_cleared_simd_clone_stat (size_t s MEM_STAT_DECL)
+{
+ return (struct simd_clone *)
+ ggc_internal_cleared_alloc_stat (s PASS_MEM_STAT);
+}
+
#endif
#include "coretypes.h"
#include "tree.h"
#include "stringpool.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "tree-ssanames.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
+#include "pointer-set.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "stringpool.h"
#include "gimplify.h"
#include "function.h"
#include "dumpfile.h"
#include "bitmap.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-fold.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimplify.h"
#include "gimple-iterator.h"
unsigned HOST_WIDE_INT indexi = offset * BITS_PER_UNIT;
tree index = bitsize_int (indexi);
if (offset / part_widthi
- <= TYPE_VECTOR_SUBPARTS (TREE_TYPE (addrtype)))
+ < TYPE_VECTOR_SUBPARTS (TREE_TYPE (addrtype)))
return fold_build3 (BIT_FIELD_REF, type, TREE_OPERAND (addr, 0),
part_width, index);
}
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "tree.h"
#include "tree-nested.h"
#include "calls.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "tree-iterator.h"
#include "gimple-pretty-print.h"
#include "hashtab.h"
#include "bitmap.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimple-ssa.h"
static void
dump_gimple_return (pretty_printer *buffer, gimple gs, int spc, int flags)
{
- tree t, t2;
+ tree t;
t = gimple_return_retval (gs);
- t2 = gimple_return_retbnd (gs);
if (flags & TDF_RAW)
- dump_gimple_fmt (buffer, spc, flags, "%G <%T %T>", gs, t, t2);
+ dump_gimple_fmt (buffer, spc, flags, "%G <%T>", gs, t);
else
{
pp_string (buffer, "return");
pp_space (buffer);
dump_generic_node (buffer, t, spc, flags, false);
}
- if (t2)
- {
- pp_string (buffer, ", ");
- dump_generic_node (buffer, t2, spc, flags, false);
- }
pp_semicolon (buffer);
}
}
tree vdef = gimple_vdef (gs);
tree vuse = gimple_vuse (gs);
- if (!ssa_operands_active (DECL_STRUCT_FUNCTION (current_function_decl))
- || !gimple_references_memory_p (gs))
- return;
-
if (vdef != NULL_TREE)
{
pp_string (buffer, "# ");
#include "tree.h"
#include "flags.h"
#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimple-walk.h"
#include "system.h"
#include "coretypes.h"
#include "tree.h"
+#include "pointer-set.h"
+#include "hash-table.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimplify-me.h"
#include "stor-layout.h"
#include "expr.h"
-#include "basic-block.h"
#include "tree-pass.h"
#include "cfgloop.h"
#include "gimple-pretty-print.h"
#include "stringpool.h"
#include "tree-ssanames.h"
#include "domwalk.h"
-#include "pointer-set.h"
#include "expmed.h"
#include "params.h"
-#include "hash-table.h"
#include "tree-ssa-address.h"
+#include "tree-affine.h"
#include "wide-int-print.h"
\f
/* Information about a strength reduction candidate. Each statement
/* Hash table embodying a mapping from base exprs to chains of candidates. */
static hash_table <cand_chain_hasher> base_cand_map;
\f
+/* Pointer map used by tree_to_aff_combination_expand. */
+static struct pointer_map_t *name_expansions;
+/* Pointer map embodying a mapping from bases to alternative bases. */
+static struct pointer_map_t *alt_base_map;
+
+/* Given BASE, use the tree affine combiniation facilities to
+ find the underlying tree expression for BASE, with any
+ immediate offset excluded. */
+
+static tree
+get_alternative_base (tree base)
+{
+ tree *result = (tree *) pointer_map_contains (alt_base_map, base);
+
+ if (result == NULL)
+ {
+ tree expr;
+ aff_tree aff;
+
+ tree_to_aff_combination_expand (base, TREE_TYPE (base),
+ &aff, &name_expansions);
+ aff.offset = 0;
+ expr = aff_combination_to_tree (&aff);
+
+ result = (tree *) pointer_map_insert (alt_base_map, base);
+ gcc_assert (!*result);
+
+ if (expr == base)
+ *result = NULL;
+ else
+ *result = expr;
+ }
+
+ return *result;
+}
+
/* Look in the candidate table for a CAND_PHI that defines BASE and
return it if found; otherwise return NULL. */
}
/* Helper routine for find_basis_for_candidate. May be called twice:
- once for the candidate's base expr, and optionally again for the
- candidate's phi definition. */
+ once for the candidate's base expr, and optionally again either for
+ the candidate's phi definition or for a CAND_REF's alternative base
+ expression. */
static slsr_cand_t
find_basis_for_base_expr (slsr_cand_t c, tree base_expr)
}
}
+ if (!basis && c->kind == CAND_REF)
+ {
+ tree alt_base_expr = get_alternative_base (c->base_expr);
+ if (alt_base_expr)
+ basis = find_basis_for_base_expr (c, alt_base_expr);
+ }
+
if (basis)
{
c->sibling = basis->dependent;
return 0;
}
-/* Record a mapping from the base expression of C to C itself, indicating that
- C may potentially serve as a basis using that base expression. */
+/* Record a mapping from BASE to C, indicating that C may potentially serve
+ as a basis using that base expression. BASE may be the same as
+ C->BASE_EXPR; alternatively BASE can be a different tree that share the
+ underlining expression of C->BASE_EXPR. */
static void
-record_potential_basis (slsr_cand_t c)
+record_potential_basis (slsr_cand_t c, tree base)
{
cand_chain_t node;
cand_chain **slot;
+ gcc_assert (base);
+
node = (cand_chain_t) obstack_alloc (&chain_obstack, sizeof (cand_chain));
- node->base_expr = c->base_expr;
+ node->base_expr = base;
node->cand = c;
node->next = NULL;
slot = base_cand_map.find_slot (node, INSERT);
}
/* Allocate storage for a new candidate and initialize its fields.
- Attempt to find a basis for the candidate. */
+ Attempt to find a basis for the candidate.
+
+ For CAND_REF, an alternative base may also be recorded and used
+ to find a basis. This helps cases where the expression hidden
+ behind BASE (which is usually an SSA_NAME) has immediate offset,
+ e.g.
+
+ a2[i][j] = 1;
+ a2[i + 20][j] = 2; */
static slsr_cand_t
-alloc_cand_and_find_basis (enum cand_kind kind, gimple gs, tree base,
+alloc_cand_and_find_basis (enum cand_kind kind, gimple gs, tree base,
const widest_int &index, tree stride, tree ctype,
unsigned savings)
{
else
c->basis = find_basis_for_candidate (c);
- record_potential_basis (c);
+ record_potential_basis (c, base);
+ if (kind == CAND_REF)
+ {
+ tree alt_base = get_alternative_base (base);
+ if (alt_base)
+ record_potential_basis (c, alt_base);
+ }
return c;
}
static void
replace_refs (slsr_cand_t c)
{
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fputs ("Replacing reference: ", dump_file);
+ print_gimple_stmt (dump_file, c->cand_stmt, 0, 0);
+ }
+
if (gimple_vdef (c->cand_stmt))
{
tree *lhs = gimple_assign_lhs_ptr (c->cand_stmt);
replace_ref (rhs, c);
}
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fputs ("With: ", dump_file);
+ print_gimple_stmt (dump_file, c->cand_stmt, 0, 0);
+ fputs ("\n", dump_file);
+ }
+
if (c->sibling)
replace_refs (lookup_cand (c->sibling));
/* Allocate the mapping from base expressions to candidate chains. */
base_cand_map.create (500);
+ /* Allocate the mapping from bases to alternative bases. */
+ alt_base_map = pointer_map_create ();
+
/* Initialize the loop optimizer. We need to detect flow across
back edges, and this gives us dominator information as well. */
loop_optimizer_init (AVOID_CFG_MODIFICATIONS);
dump_cand_chains ();
}
+ pointer_map_destroy (alt_base_map);
+ free_affine_expand_cache (&name_expansions);
+
/* Analyze costs and make appropriate replacements. */
analyze_candidates_and_replace ();
if (gimple_has_ops (s))
{
gimple_set_modified (s, true);
- update_stmt_operands (s);
+ update_stmt_operands (cfun, s);
}
}
update_stmt_if_modified (gimple s)
{
if (gimple_modified_p (s))
- update_stmt_operands (s);
+ update_stmt_operands (cfun, s);
+}
+
+/* Mark statement S as modified, and update it. */
+
+static inline void
+update_stmt_fn (struct function *fn, gimple s)
+{
+ if (gimple_has_ops (s))
+ {
+ gimple_set_modified (s, true);
+ update_stmt_operands (fn, s);
+ }
}
#include "coretypes.h"
#include "diagnostic.h"
#include "tree.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "system.h"
#include "coretypes.h"
#include "tree.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "tm.h"
#include "tree.h"
#include "stmt.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimple-walk.h"
#include "calls.h"
#include "stmt.h"
#include "stor-layout.h"
-#include "ggc.h"
#include "hard-reg-set.h"
#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimple-walk.h"
gimple
gimple_build_return (tree retval)
{
- gimple s = gimple_build_with_ops (GIMPLE_RETURN, ERROR_MARK, 2);
+ gimple s = gimple_build_with_ops (GIMPLE_RETURN, ERROR_MARK, 1);
if (retval)
gimple_return_set_retval (s, retval);
return s;
gimple
gimple_build_resx (int region)
{
- gimple_statement_eh_ctrl *p =
- as_a <gimple_statement_eh_ctrl> (
+ gimple_statement_resx *p =
+ as_a <gimple_statement_resx> (
gimple_build_with_ops (GIMPLE_RESX, ERROR_MARK, 0));
p->region = region;
return p;
gimple
gimple_build_eh_dispatch (int region)
{
- gimple_statement_eh_ctrl *p =
- as_a <gimple_statement_eh_ctrl> (
+ gimple_statement_eh_dispatch *p =
+ as_a <gimple_statement_eh_dispatch> (
gimple_build_with_ops (GIMPLE_EH_DISPATCH, ERROR_MARK, 0));
p->region = region;
return p;
#undef DEFTREECODE
#undef END_OF_BASE_TREE_CODES
-void
-recalculate_side_effects (tree t)
-{
- enum tree_code code = TREE_CODE (t);
- int len = TREE_OPERAND_LENGTH (t);
- int i;
-
- switch (TREE_CODE_CLASS (code))
- {
- case tcc_expression:
- switch (code)
- {
- case INIT_EXPR:
- case MODIFY_EXPR:
- case VA_ARG_EXPR:
- case PREDECREMENT_EXPR:
- case PREINCREMENT_EXPR:
- case POSTDECREMENT_EXPR:
- case POSTINCREMENT_EXPR:
- /* All of these have side-effects, no matter what their
- operands are. */
- return;
-
- default:
- break;
- }
- /* Fall through. */
-
- case tcc_comparison: /* a comparison expression */
- case tcc_unary: /* a unary arithmetic expression */
- case tcc_binary: /* a binary arithmetic expression */
- case tcc_reference: /* a reference */
- case tcc_vl_exp: /* a function call */
- TREE_SIDE_EFFECTS (t) = TREE_THIS_VOLATILE (t);
- for (i = 0; i < len; ++i)
- {
- tree op = TREE_OPERAND (t, i);
- if (op && TREE_SIDE_EFFECTS (op))
- TREE_SIDE_EFFECTS (t) = 1;
- }
- break;
-
- case tcc_constant:
- /* No side-effects. */
- return;
-
- default:
- gcc_unreachable ();
- }
-}
-
/* Canonicalize a tree T for use in a COND_EXPR as conditional. Returns
a canonicalized tree that is valid for a COND_EXPR or NULL_TREE, if
we failed to create one. */
DEFGSCODE(GIMPLE_OMP_ATOMIC_LOAD, "gimple_omp_atomic_load",
GSS_OMP_ATOMIC_LOAD)
DEFGSCODE(GIMPLE_OMP_ATOMIC_STORE, "gimple_omp_atomic_store",
- GSS_OMP_ATOMIC_STORE)
+ GSS_OMP_ATOMIC_STORE_LAYOUT)
/* GIMPLE_OMP_CONTINUE marks the location of the loop or sections
iteration in partially lowered OpenMP code. */
DATA_ARG is a local variable in the parent function containing data
to be shared with CHILD_FN. This is used to implement all the data
sharing clauses. */
-DEFGSCODE(GIMPLE_OMP_PARALLEL, "gimple_omp_parallel", GSS_OMP_PARALLEL)
+DEFGSCODE(GIMPLE_OMP_PARALLEL, "gimple_omp_parallel", GSS_OMP_PARALLEL_LAYOUT)
/* GIMPLE_OMP_TASK <BODY, CLAUSES, CHILD_FN, DATA_ARG, COPY_FN,
ARG_SIZE, ARG_ALIGN> represents
DEFGSCODE(GIMPLE_OMP_TASK, "gimple_omp_task", GSS_OMP_TASK)
/* OMP_RETURN marks the end of an OpenMP directive. */
-DEFGSCODE(GIMPLE_OMP_RETURN, "gimple_omp_return", GSS_OMP_ATOMIC_STORE)
+DEFGSCODE(GIMPLE_OMP_RETURN, "gimple_omp_return", GSS_OMP_ATOMIC_STORE_LAYOUT)
/* OMP_SECTION <BODY> represents #pragma omp section.
BODY is the sequence of statements in the section body. */
/* GIMPLE_OMP_SINGLE <BODY, CLAUSES> represents #pragma omp single
BODY is the sequence of statements inside the single section.
CLAUSES is an OMP_CLAUSE chain holding the associated clauses. */
-DEFGSCODE(GIMPLE_OMP_SINGLE, "gimple_omp_single", GSS_OMP_SINGLE)
+DEFGSCODE(GIMPLE_OMP_SINGLE, "gimple_omp_single", GSS_OMP_SINGLE_LAYOUT)
/* GIMPLE_OMP_TARGET <BODY, CLAUSES, CHILD_FN> represents
#pragma omp target {,data,update}
DATA_ARG is a vec of 3 local variables in the parent function
containing data to be mapped to CHILD_FN. This is used to
implement the MAP clauses. */
-DEFGSCODE(GIMPLE_OMP_TARGET, "gimple_omp_target", GSS_OMP_PARALLEL)
+DEFGSCODE(GIMPLE_OMP_TARGET, "gimple_omp_target", GSS_OMP_PARALLEL_LAYOUT)
/* GIMPLE_OMP_TEAMS <BODY, CLAUSES> represents #pragma omp teams
BODY is the sequence of statements inside the single section.
CLAUSES is an OMP_CLAUSE chain holding the associated clauses. */
-DEFGSCODE(GIMPLE_OMP_TEAMS, "gimple_omp_teams", GSS_OMP_SINGLE)
+DEFGSCODE(GIMPLE_OMP_TEAMS, "gimple_omp_teams", GSS_OMP_SINGLE_LAYOUT)
/* GIMPLE_PREDICT <PREDICT, OUTCOME> specifies a hint for branch prediction.
#ifndef GCC_GIMPLE_H
#define GCC_GIMPLE_H
-#include "pointer-set.h"
-#include "hash-table.h"
-#include "vec.h"
-#include "ggc.h"
-#include "basic-block.h"
-#include "tree-ssa-alias.h"
-#include "internal-fn.h"
-#include "gimple-fold.h"
-#include "tree-eh.h"
-#include "gimple-expr.h"
-#include "is-a.h"
-
typedef gimple gimple_seq_node;
/* For each block, the PHI nodes that need to be rewritten are stored into
GF_CALL_NOTHROW = 1 << 4,
GF_CALL_ALLOCA_FOR_VAR = 1 << 5,
GF_CALL_INTERNAL = 1 << 6,
- GF_CALL_WITH_BOUNDS = 1 << 7,
GF_OMP_PARALLEL_COMBINED = 1 << 0,
GF_OMP_FOR_KIND_MASK = 3 << 0,
GF_OMP_FOR_KIND_FOR = 0 << 0,
int region;
};
+struct GTY((tag("GSS_EH_CTRL")))
+ gimple_statement_resx : public gimple_statement_eh_ctrl
+{
+ /* No extra fields; adds invariant:
+ stmt->code == GIMPLE_RESX. */
+};
+
+struct GTY((tag("GSS_EH_CTRL")))
+ gimple_statement_eh_dispatch : public gimple_statement_eh_ctrl
+{
+ /* No extra fields; adds invariant:
+ stmt->code == GIMPLE_EH_DISPATH. */
+};
+
/* GIMPLE_TRY */
};
-/* GIMPLE_OMP_PARALLEL */
-
-struct GTY((tag("GSS_OMP_PARALLEL")))
- gimple_statement_omp_parallel : public gimple_statement_omp
+/* GIMPLE_OMP_PARALLEL, GIMPLE_OMP_TARGET */
+struct GTY((tag("GSS_OMP_PARALLEL_LAYOUT")))
+ gimple_statement_omp_parallel_layout : public gimple_statement_omp
{
/* [ WORD 1-7 ] : base class */
tree data_arg;
};
+/* GIMPLE_OMP_PARALLEL or GIMPLE_TASK */
+struct GTY((tag("GSS_OMP_PARALLEL_LAYOUT")))
+ gimple_statement_omp_taskreg : public gimple_statement_omp_parallel_layout
+{
+ /* No extra fields; adds invariant:
+ stmt->code == GIMPLE_OMP_PARALLEL
+ || stmt->code == GIMPLE_OMP_TASK. */
+};
+
+
+/* GIMPLE_OMP_PARALLEL */
+struct GTY((tag("GSS_OMP_PARALLEL_LAYOUT")))
+ gimple_statement_omp_parallel : public gimple_statement_omp_taskreg
+{
+ /* No extra fields; adds invariant:
+ stmt->code == GIMPLE_OMP_PARALLEL. */
+};
+
+struct GTY((tag("GSS_OMP_PARALLEL_LAYOUT")))
+ gimple_statement_omp_target : public gimple_statement_omp_parallel_layout
+{
+ /* No extra fields; adds invariant:
+ stmt->code == GIMPLE_OMP_TARGET. */
+};
/* GIMPLE_OMP_TASK */
struct GTY((tag("GSS_OMP_TASK")))
- gimple_statement_omp_task : public gimple_statement_omp_parallel
+ gimple_statement_omp_task : public gimple_statement_omp_taskreg
{
/* [ WORD 1-10 ] : base class */
tree control_use;
};
-/* GIMPLE_OMP_SINGLE, GIMPLE_OMP_TARGET, GIMPLE_OMP_TEAMS */
+/* GIMPLE_OMP_SINGLE, GIMPLE_OMP_TEAMS */
-struct GTY((tag("GSS_OMP_SINGLE")))
- gimple_statement_omp_single : public gimple_statement_omp
+struct GTY((tag("GSS_OMP_SINGLE_LAYOUT")))
+ gimple_statement_omp_single_layout : public gimple_statement_omp
{
/* [ WORD 1-7 ] : base class */
tree clauses;
};
+struct GTY((tag("GSS_OMP_SINGLE_LAYOUT")))
+ gimple_statement_omp_single : public gimple_statement_omp_single_layout
+{
+ /* No extra fields; adds invariant:
+ stmt->code == GIMPLE_OMP_SINGLE. */
+};
+
+struct GTY((tag("GSS_OMP_SINGLE_LAYOUT")))
+ gimple_statement_omp_teams : public gimple_statement_omp_single_layout
+{
+ /* No extra fields; adds invariant:
+ stmt->code == GIMPLE_OMP_TEAMS. */
+};
+
/* GIMPLE_OMP_ATOMIC_LOAD.
Note: This is based on gimple_statement_base, not g_s_omp, because g_s_omp
/* GIMPLE_OMP_ATOMIC_STORE.
See note on GIMPLE_OMP_ATOMIC_LOAD. */
-struct GTY((tag("GSS_OMP_ATOMIC_STORE")))
- gimple_statement_omp_atomic_store : public gimple_statement_base
+struct GTY((tag("GSS_OMP_ATOMIC_STORE_LAYOUT")))
+ gimple_statement_omp_atomic_store_layout : public gimple_statement_base
{
/* [ WORD 1-6 ] : base class */
tree val;
};
+struct GTY((tag("GSS_OMP_ATOMIC_STORE_LAYOUT")))
+ gimple_statement_omp_atomic_store :
+ public gimple_statement_omp_atomic_store_layout
+{
+ /* No extra fields; adds invariant:
+ stmt->code == GIMPLE_OMP_ATOMIC_STORE. */
+};
+
+struct GTY((tag("GSS_OMP_ATOMIC_STORE_LAYOUT")))
+ gimple_statement_omp_return :
+ public gimple_statement_omp_atomic_store_layout
+{
+ /* No extra fields; adds invariant:
+ stmt->code == GIMPLE_OMP_RETURN. */
+};
+
/* GIMPLE_TRANSACTION. */
/* Bits to be stored in the GIMPLE_TRANSACTION subcode. */
template <>
template <>
inline bool
-is_a_helper <gimple_statement_eh_ctrl>::test (gimple gs)
+is_a_helper <gimple_statement_resx>::test (gimple gs)
+{
+ return gs->code == GIMPLE_RESX;
+}
+
+template <>
+template <>
+inline bool
+is_a_helper <gimple_statement_eh_dispatch>::test (gimple gs)
{
- return gs->code == GIMPLE_RESX || gs->code == GIMPLE_EH_DISPATCH;
+ return gs->code == GIMPLE_EH_DISPATCH;
}
template <>
inline bool
is_a_helper <gimple_statement_omp_atomic_store>::test (gimple gs)
{
- return gs->code == GIMPLE_OMP_ATOMIC_STORE || gs->code == GIMPLE_OMP_RETURN;
+ return gs->code == GIMPLE_OMP_ATOMIC_STORE;
+}
+
+template <>
+template <>
+inline bool
+is_a_helper <gimple_statement_omp_return>::test (gimple gs)
+{
+ return gs->code == GIMPLE_OMP_RETURN;
}
template <>
return gs->code == GIMPLE_OMP_FOR;
}
+template <>
+template <>
+inline bool
+is_a_helper <gimple_statement_omp_taskreg>::test (gimple gs)
+{
+ return gs->code == GIMPLE_OMP_PARALLEL || gs->code == GIMPLE_OMP_TASK;
+}
+
template <>
template <>
inline bool
is_a_helper <gimple_statement_omp_parallel>::test (gimple gs)
{
- return gs->code == GIMPLE_OMP_PARALLEL || gs->code == GIMPLE_OMP_TASK || gs->code == GIMPLE_OMP_TARGET;
+ return gs->code == GIMPLE_OMP_PARALLEL;
+}
+
+template <>
+template <>
+inline bool
+is_a_helper <gimple_statement_omp_target>::test (gimple gs)
+{
+ return gs->code == GIMPLE_OMP_TARGET;
}
template <>
inline bool
is_a_helper <gimple_statement_omp_single>::test (gimple gs)
{
- return gs->code == GIMPLE_OMP_SINGLE || gs->code == GIMPLE_OMP_TEAMS;
+ return gs->code == GIMPLE_OMP_SINGLE;
+}
+
+template <>
+template <>
+inline bool
+is_a_helper <gimple_statement_omp_teams>::test (gimple gs)
+{
+ return gs->code == GIMPLE_OMP_TEAMS;
}
template <>
template <>
template <>
inline bool
-is_a_helper <const gimple_statement_eh_ctrl>::test (const_gimple gs)
+is_a_helper <const gimple_statement_resx>::test (const_gimple gs)
+{
+ return gs->code == GIMPLE_RESX;
+}
+
+template <>
+template <>
+inline bool
+is_a_helper <const gimple_statement_eh_dispatch>::test (const_gimple gs)
{
- return gs->code == GIMPLE_RESX || gs->code == GIMPLE_EH_DISPATCH;
+ return gs->code == GIMPLE_EH_DISPATCH;
}
template <>
inline bool
is_a_helper <const gimple_statement_omp_atomic_store>::test (const_gimple gs)
{
- return gs->code == GIMPLE_OMP_ATOMIC_STORE || gs->code == GIMPLE_OMP_RETURN;
+ return gs->code == GIMPLE_OMP_ATOMIC_STORE;
+}
+
+template <>
+template <>
+inline bool
+is_a_helper <const gimple_statement_omp_return>::test (const_gimple gs)
+{
+ return gs->code == GIMPLE_OMP_RETURN;
}
template <>
return gs->code == GIMPLE_OMP_FOR;
}
+template <>
+template <>
+inline bool
+is_a_helper <const gimple_statement_omp_taskreg>::test (const_gimple gs)
+{
+ return gs->code == GIMPLE_OMP_PARALLEL || gs->code == GIMPLE_OMP_TASK;
+}
+
template <>
template <>
inline bool
is_a_helper <const gimple_statement_omp_parallel>::test (const_gimple gs)
{
- return gs->code == GIMPLE_OMP_PARALLEL || gs->code == GIMPLE_OMP_TASK || gs->code == GIMPLE_OMP_TARGET;
+ return gs->code == GIMPLE_OMP_PARALLEL;
+}
+
+template <>
+template <>
+inline bool
+is_a_helper <const gimple_statement_omp_target>::test (const_gimple gs)
+{
+ return gs->code == GIMPLE_OMP_TARGET;
}
template <>
inline bool
is_a_helper <const gimple_statement_omp_single>::test (const_gimple gs)
{
- return gs->code == GIMPLE_OMP_SINGLE || gs->code == GIMPLE_OMP_TEAMS;
+ return gs->code == GIMPLE_OMP_SINGLE;
+}
+
+template <>
+template <>
+inline bool
+is_a_helper <const gimple_statement_omp_teams>::test (const_gimple gs)
+{
+ return gs->code == GIMPLE_OMP_TEAMS;
}
template <>
bool gimple_assign_rhs_could_trap_p (gimple);
extern void dump_gimple_statistics (void);
unsigned get_gimple_rhs_num_ops (enum tree_code);
-extern void recalculate_side_effects (tree);
extern tree canonicalize_cond_expr_cond (tree);
gimple gimple_call_copy_skip_args (gimple, bitmap);
extern bool gimple_compare_field_offset (tree, tree);
static inline void
gimple_omp_return_set_lhs (gimple g, tree lhs)
{
- gimple_statement_omp_atomic_store *omp_atomic_store_stmt =
- as_a <gimple_statement_omp_atomic_store> (g);
- omp_atomic_store_stmt->val = lhs;
+ gimple_statement_omp_return *omp_return_stmt =
+ as_a <gimple_statement_omp_return> (g);
+ omp_return_stmt->val = lhs;
}
static inline tree
gimple_omp_return_lhs (const_gimple g)
{
- const gimple_statement_omp_atomic_store *omp_atomic_store_stmt =
- as_a <const gimple_statement_omp_atomic_store> (g);
- return omp_atomic_store_stmt->val;
+ const gimple_statement_omp_return *omp_return_stmt =
+ as_a <const gimple_statement_omp_return> (g);
+ return omp_return_stmt->val;
}
static inline tree *
gimple_omp_return_lhs_ptr (gimple g)
{
- gimple_statement_omp_atomic_store *omp_atomic_store_stmt =
- as_a <gimple_statement_omp_atomic_store> (g);
- return &omp_atomic_store_stmt->val;
+ gimple_statement_omp_return *omp_return_stmt =
+ as_a <gimple_statement_omp_return> (g);
+ return &omp_return_stmt->val;
}
}
-/* Return true if call GS is marked as instrumented by
- Pointer Bounds Checker. */
-
-static inline bool
-gimple_call_with_bounds_p (const_gimple gs)
-{
- GIMPLE_CHECK (gs, GIMPLE_CALL);
- return (gs->subcode & GF_CALL_WITH_BOUNDS) != 0;
-}
-
-
-/* If INSTRUMENTED_P is true, marm statement GS as instrumented by
- Pointer Bounds Checker. */
-
-static inline void
-gimple_call_set_with_bounds (gimple gs, bool with_bounds)
-{
- GIMPLE_CHECK (gs, GIMPLE_CALL);
- if (with_bounds)
- gs->subcode |= GF_CALL_WITH_BOUNDS;
- else
- gs->subcode &= ~GF_CALL_WITH_BOUNDS;
-}
-
-
/* Return the target of internal call GS. */
static inline enum internal_fn
static inline int
gimple_resx_region (const_gimple gs)
{
- const gimple_statement_eh_ctrl *eh_ctrl_stmt =
- as_a <const gimple_statement_eh_ctrl> (gs);
- return eh_ctrl_stmt->region;
+ const gimple_statement_resx *resx_stmt =
+ as_a <const gimple_statement_resx> (gs);
+ return resx_stmt->region;
}
/* Set REGION to be the region number for GIMPLE_RESX GS. */
static inline void
gimple_resx_set_region (gimple gs, int region)
{
- gimple_statement_eh_ctrl *eh_ctrl_stmt =
- as_a <gimple_statement_eh_ctrl> (gs);
- eh_ctrl_stmt->region = region;
+ gimple_statement_resx *resx_stmt = as_a <gimple_statement_resx> (gs);
+ resx_stmt->region = region;
}
/* Return the region number for GIMPLE_EH_DISPATCH GS. */
static inline int
gimple_eh_dispatch_region (const_gimple gs)
{
- const gimple_statement_eh_ctrl *eh_ctrl_stmt =
- as_a <const gimple_statement_eh_ctrl> (gs);
- return eh_ctrl_stmt->region;
+ const gimple_statement_eh_dispatch *eh_dispatch_stmt =
+ as_a <const gimple_statement_eh_dispatch> (gs);
+ return eh_dispatch_stmt->region;
}
/* Set REGION to be the region number for GIMPLE_EH_DISPATCH GS. */
static inline void
gimple_eh_dispatch_set_region (gimple gs, int region)
{
- gimple_statement_eh_ctrl *eh_ctrl_stmt =
- as_a <gimple_statement_eh_ctrl> (gs);
- eh_ctrl_stmt->region = region;
+ gimple_statement_eh_dispatch *eh_dispatch_stmt =
+ as_a <gimple_statement_eh_dispatch> (gs);
+ eh_dispatch_stmt->region = region;
}
/* Return the number of labels associated with the switch statement GS. */
static inline tree
gimple_omp_taskreg_clauses (const_gimple gs)
{
- const gimple_statement_omp_parallel *omp_parallel_stmt =
- as_a <const gimple_statement_omp_parallel> (gs);
- return omp_parallel_stmt->clauses;
+ const gimple_statement_omp_taskreg *omp_taskreg_stmt =
+ as_a <const gimple_statement_omp_taskreg> (gs);
+ return omp_taskreg_stmt->clauses;
}
static inline tree *
gimple_omp_taskreg_clauses_ptr (gimple gs)
{
- gimple_statement_omp_parallel *omp_parallel_stmt =
- as_a <gimple_statement_omp_parallel> (gs);
- return &omp_parallel_stmt->clauses;
+ gimple_statement_omp_taskreg *omp_taskreg_stmt =
+ as_a <gimple_statement_omp_taskreg> (gs);
+ return &omp_taskreg_stmt->clauses;
}
static inline void
gimple_omp_taskreg_set_clauses (gimple gs, tree clauses)
{
- gimple_statement_omp_parallel *omp_parallel_stmt =
- as_a <gimple_statement_omp_parallel> (gs);
- omp_parallel_stmt->clauses = clauses;
+ gimple_statement_omp_taskreg *omp_taskreg_stmt =
+ as_a <gimple_statement_omp_taskreg> (gs);
+ omp_taskreg_stmt->clauses = clauses;
}
static inline tree
gimple_omp_taskreg_child_fn (const_gimple gs)
{
- const gimple_statement_omp_parallel *omp_parallel_stmt =
- as_a <const gimple_statement_omp_parallel> (gs);
- return omp_parallel_stmt->child_fn;
+ const gimple_statement_omp_taskreg *omp_taskreg_stmt =
+ as_a <const gimple_statement_omp_taskreg> (gs);
+ return omp_taskreg_stmt->child_fn;
}
/* Return a pointer to the child function used to hold the body of
static inline tree *
gimple_omp_taskreg_child_fn_ptr (gimple gs)
{
- gimple_statement_omp_parallel *omp_parallel_stmt =
- as_a <gimple_statement_omp_parallel> (gs);
- return &omp_parallel_stmt->child_fn;
+ gimple_statement_omp_taskreg *omp_taskreg_stmt =
+ as_a <gimple_statement_omp_taskreg> (gs);
+ return &omp_taskreg_stmt->child_fn;
}
static inline void
gimple_omp_taskreg_set_child_fn (gimple gs, tree child_fn)
{
- gimple_statement_omp_parallel *omp_parallel_stmt =
- as_a <gimple_statement_omp_parallel> (gs);
- omp_parallel_stmt->child_fn = child_fn;
+ gimple_statement_omp_taskreg *omp_taskreg_stmt =
+ as_a <gimple_statement_omp_taskreg> (gs);
+ omp_taskreg_stmt->child_fn = child_fn;
}
static inline tree
gimple_omp_taskreg_data_arg (const_gimple gs)
{
- const gimple_statement_omp_parallel *omp_parallel_stmt =
- as_a <const gimple_statement_omp_parallel> (gs);
- return omp_parallel_stmt->data_arg;
+ const gimple_statement_omp_taskreg *omp_taskreg_stmt =
+ as_a <const gimple_statement_omp_taskreg> (gs);
+ return omp_taskreg_stmt->data_arg;
}
static inline tree *
gimple_omp_taskreg_data_arg_ptr (gimple gs)
{
- gimple_statement_omp_parallel *omp_parallel_stmt =
- as_a <gimple_statement_omp_parallel> (gs);
- return &omp_parallel_stmt->data_arg;
+ gimple_statement_omp_taskreg *omp_taskreg_stmt =
+ as_a <gimple_statement_omp_taskreg> (gs);
+ return &omp_taskreg_stmt->data_arg;
}
static inline void
gimple_omp_taskreg_set_data_arg (gimple gs, tree data_arg)
{
- gimple_statement_omp_parallel *omp_parallel_stmt =
- as_a <gimple_statement_omp_parallel> (gs);
- omp_parallel_stmt->data_arg = data_arg;
+ gimple_statement_omp_taskreg *omp_taskreg_stmt =
+ as_a <gimple_statement_omp_taskreg> (gs);
+ omp_taskreg_stmt->data_arg = data_arg;
}
static inline tree
gimple_omp_target_clauses (const_gimple gs)
{
- const gimple_statement_omp_parallel *omp_parallel_stmt =
- as_a <const gimple_statement_omp_parallel> (gs);
- return omp_parallel_stmt->clauses;
+ const gimple_statement_omp_target *omp_target_stmt =
+ as_a <const gimple_statement_omp_target> (gs);
+ return omp_target_stmt->clauses;
}
static inline tree *
gimple_omp_target_clauses_ptr (gimple gs)
{
- gimple_statement_omp_parallel *omp_parallel_stmt =
- as_a <gimple_statement_omp_parallel> (gs);
- return &omp_parallel_stmt->clauses;
+ gimple_statement_omp_target *omp_target_stmt =
+ as_a <gimple_statement_omp_target> (gs);
+ return &omp_target_stmt->clauses;
}
static inline void
gimple_omp_target_set_clauses (gimple gs, tree clauses)
{
- gimple_statement_omp_parallel *omp_parallel_stmt =
- as_a <gimple_statement_omp_parallel> (gs);
- omp_parallel_stmt->clauses = clauses;
+ gimple_statement_omp_target *omp_target_stmt =
+ as_a <gimple_statement_omp_target> (gs);
+ omp_target_stmt->clauses = clauses;
}
static inline tree
gimple_omp_target_child_fn (const_gimple gs)
{
- const gimple_statement_omp_parallel *omp_parallel_stmt =
- as_a <const gimple_statement_omp_parallel> (gs);
- return omp_parallel_stmt->child_fn;
+ const gimple_statement_omp_target *omp_target_stmt =
+ as_a <const gimple_statement_omp_target> (gs);
+ return omp_target_stmt->child_fn;
}
/* Return a pointer to the child function used to hold the body of
static inline tree *
gimple_omp_target_child_fn_ptr (gimple gs)
{
- gimple_statement_omp_parallel *omp_parallel_stmt =
- as_a <gimple_statement_omp_parallel> (gs);
- return &omp_parallel_stmt->child_fn;
+ gimple_statement_omp_target *omp_target_stmt =
+ as_a <gimple_statement_omp_target> (gs);
+ return &omp_target_stmt->child_fn;
}
static inline void
gimple_omp_target_set_child_fn (gimple gs, tree child_fn)
{
- gimple_statement_omp_parallel *omp_parallel_stmt =
- as_a <gimple_statement_omp_parallel> (gs);
- omp_parallel_stmt->child_fn = child_fn;
+ gimple_statement_omp_target *omp_target_stmt =
+ as_a <gimple_statement_omp_target> (gs);
+ omp_target_stmt->child_fn = child_fn;
}
static inline tree
gimple_omp_target_data_arg (const_gimple gs)
{
- const gimple_statement_omp_parallel *omp_parallel_stmt =
- as_a <const gimple_statement_omp_parallel> (gs);
- return omp_parallel_stmt->data_arg;
+ const gimple_statement_omp_target *omp_target_stmt =
+ as_a <const gimple_statement_omp_target> (gs);
+ return omp_target_stmt->data_arg;
}
static inline tree *
gimple_omp_target_data_arg_ptr (gimple gs)
{
- gimple_statement_omp_parallel *omp_parallel_stmt =
- as_a <gimple_statement_omp_parallel> (gs);
- return &omp_parallel_stmt->data_arg;
+ gimple_statement_omp_target *omp_target_stmt =
+ as_a <gimple_statement_omp_target> (gs);
+ return &omp_target_stmt->data_arg;
}
static inline void
gimple_omp_target_set_data_arg (gimple gs, tree data_arg)
{
- gimple_statement_omp_parallel *omp_parallel_stmt =
- as_a <gimple_statement_omp_parallel> (gs);
- omp_parallel_stmt->data_arg = data_arg;
+ gimple_statement_omp_target *omp_target_stmt =
+ as_a <gimple_statement_omp_target> (gs);
+ omp_target_stmt->data_arg = data_arg;
}
static inline tree
gimple_omp_teams_clauses (const_gimple gs)
{
- const gimple_statement_omp_single *omp_single_stmt =
- as_a <const gimple_statement_omp_single> (gs);
- return omp_single_stmt->clauses;
+ const gimple_statement_omp_teams *omp_teams_stmt =
+ as_a <const gimple_statement_omp_teams> (gs);
+ return omp_teams_stmt->clauses;
}
static inline tree *
gimple_omp_teams_clauses_ptr (gimple gs)
{
- gimple_statement_omp_single *omp_single_stmt =
- as_a <gimple_statement_omp_single> (gs);
- return &omp_single_stmt->clauses;
+ gimple_statement_omp_teams *omp_teams_stmt =
+ as_a <gimple_statement_omp_teams> (gs);
+ return &omp_teams_stmt->clauses;
}
static inline void
gimple_omp_teams_set_clauses (gimple gs, tree clauses)
{
- gimple_statement_omp_single *omp_single_stmt =
- as_a <gimple_statement_omp_single> (gs);
- omp_single_stmt->clauses = clauses;
+ gimple_statement_omp_teams *omp_teams_stmt =
+ as_a <gimple_statement_omp_teams> (gs);
+ omp_teams_stmt->clauses = clauses;
}
}
-/* Return the return bounds for GIMPLE_RETURN GS. */
-
-static inline tree
-gimple_return_retbnd (const_gimple gs)
-{
- GIMPLE_CHECK (gs, GIMPLE_RETURN);
- return gimple_op (gs, 1);
-}
-
-
-/* Set RETVAL to be the return bounds for GIMPLE_RETURN GS. */
-
-static inline void
-gimple_return_set_retbnd (gimple gs, tree retval)
-{
- GIMPLE_CHECK (gs, GIMPLE_RETURN);
- gimple_set_op (gs, 1, retval);
-}
-
-
/* Returns true when the gimple statement STMT is any of the OpenMP types. */
#define CASE_GIMPLE_OMP \
#include "tree.h"
#include "stmt.h"
#include "stor-layout.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimplify.h"
#include "coretypes.h"
#include "tree.h"
#include "expr.h"
+#include "pointer-set.h"
+#include "hash-table.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-fold.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimplify.h"
#include "gimple-iterator.h"
mod = build2 (INIT_EXPR, TREE_TYPE (t), t, unshare_expr (val));
- SET_EXPR_LOCATION (mod, EXPR_LOC_OR_HERE (val));
+ SET_EXPR_LOCATION (mod, EXPR_LOC_OR_LOC (val, input_location));
/* gimplify_modify_expr might want to reduce this further. */
gimplify_and_add (mod, pre_p);
/* Nonlocal VLAs seen in the current function. */
static struct pointer_set_t *nonlocal_vlas;
+/* The VAR_DECLs created for nonlocal VLAs for debug info purposes. */
+static tree nonlocal_vla_vars;
+
/* Gimplify a VAR_DECL or PARM_DECL. Return GS_OK if we expanded a
DECL_VALUE_EXPR, and it's worth re-examining things. */
ctx = ctx->outer_context;
if (!ctx && !pointer_set_insert (nonlocal_vlas, decl))
{
- tree copy = copy_node (decl), block;
+ tree copy = copy_node (decl);
lang_hooks.dup_lang_specific_decl (copy);
SET_DECL_RTL (copy, 0);
TREE_USED (copy) = 1;
- block = DECL_INITIAL (current_function_decl);
- DECL_CHAIN (copy) = BLOCK_VARS (block);
- BLOCK_VARS (block) = copy;
+ DECL_CHAIN (copy) = nonlocal_vla_vars;
+ nonlocal_vla_vars = copy;
SET_DECL_VALUE_EXPR (copy, unshare_expr (value_expr));
DECL_HAS_VALUE_EXPR_P (copy) = 1;
}
return GS_ALL_DONE;
}
+/* Recalculate the value of the TREE_SIDE_EFFECTS flag for T. */
+
+static void
+recalculate_side_effects (tree t)
+{
+ enum tree_code code = TREE_CODE (t);
+ int len = TREE_OPERAND_LENGTH (t);
+ int i;
+
+ switch (TREE_CODE_CLASS (code))
+ {
+ case tcc_expression:
+ switch (code)
+ {
+ case INIT_EXPR:
+ case MODIFY_EXPR:
+ case VA_ARG_EXPR:
+ case PREDECREMENT_EXPR:
+ case PREINCREMENT_EXPR:
+ case POSTDECREMENT_EXPR:
+ case POSTINCREMENT_EXPR:
+ /* All of these have side-effects, no matter what their
+ operands are. */
+ return;
+
+ default:
+ break;
+ }
+ /* Fall through. */
+
+ case tcc_comparison: /* a comparison expression */
+ case tcc_unary: /* a unary arithmetic expression */
+ case tcc_binary: /* a binary arithmetic expression */
+ case tcc_reference: /* a reference */
+ case tcc_vl_exp: /* a function call */
+ TREE_SIDE_EFFECTS (t) = TREE_THIS_VOLATILE (t);
+ for (i = 0; i < len; ++i)
+ {
+ tree op = TREE_OPERAND (t, i);
+ if (op && TREE_SIDE_EFFECTS (op))
+ TREE_SIDE_EFFECTS (t) = 1;
+ }
+ break;
+
+ case tcc_constant:
+ /* No side-effects. */
+ return;
+
+ default:
+ gcc_unreachable ();
+ }
+}
+
/* Gimplify the COMPONENT_REF, ARRAY_REF, REALPART_EXPR or IMAGPART_EXPR
node *EXPR_P.
while (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
{
/* Keep the original source location on the first 'if'. */
- location_t locus = EXPR_LOC_OR_HERE (expr);
+ location_t locus = EXPR_LOC_OR_LOC (expr, input_location);
TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
/* Set the source location of the && on the second 'if'. */
if (EXPR_HAS_LOCATION (pred))
while (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
{
/* Keep the original source location on the first 'if'. */
- location_t locus = EXPR_LOC_OR_HERE (expr);
+ location_t locus = EXPR_LOC_OR_LOC (expr, input_location);
TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
/* Set the source location of the || on the second 'if'. */
if (EXPR_HAS_LOCATION (pred))
/* If there was nothing else in our arms, just forward the label(s). */
if (!then_se && !else_se)
return shortcut_cond_r (pred, true_label_p, false_label_p,
- EXPR_LOC_OR_HERE (expr));
+ EXPR_LOC_OR_LOC (expr, input_location));
/* If our last subexpression already has a terminal label, reuse it. */
if (else_se)
jump_over_else = block_may_fallthru (then_);
pred = shortcut_cond_r (pred, true_label_p, false_label_p,
- EXPR_LOC_OR_HERE (expr));
+ EXPR_LOC_OR_LOC (expr, input_location));
expr = NULL;
append_to_statement_list (pred, &expr);
individual element initialization. Also don't do this for small
all-zero initializers (which aren't big enough to merit
clearing), and don't try to make bitwise copies of
- TREE_ADDRESSABLE types.
-
- We cannot apply such transformation when compiling chkp static
- initializer because creation of initializer image in the memory
- will require static initialization of bounds for it. It should
- result in another gimplification of similar initializer and we
- may fall into infinite loop. */
+ TREE_ADDRESSABLE types. */
if (valid_const_initializer
&& !(cleared || num_nonzero_elements == 0)
- && !TREE_ADDRESSABLE (type)
- && (!current_function_decl
- || !lookup_attribute ("chkp ctor",
- DECL_ATTRIBUTES (current_function_decl))))
+ && !TREE_ADDRESSABLE (type))
{
HOST_WIDE_INT size = int_size_in_bytes (type);
unsigned int align;
if (nonlocal_vlas)
{
+ if (nonlocal_vla_vars)
+ {
+ /* tree-nested.c may later on call declare_vars (..., true);
+ which relies on BLOCK_VARS chain to be the tail of the
+ gimple_bind_vars chain. Ensure we don't violate that
+ assumption. */
+ if (gimple_bind_block (outer_bind)
+ == DECL_INITIAL (current_function_decl))
+ declare_vars (nonlocal_vla_vars, outer_bind, true);
+ else
+ BLOCK_VARS (DECL_INITIAL (current_function_decl))
+ = chainon (BLOCK_VARS (DECL_INITIAL (current_function_decl)),
+ nonlocal_vla_vars);
+ nonlocal_vla_vars = NULL_TREE;
+ }
pointer_set_destroy (nonlocal_vlas);
nonlocal_vlas = NULL;
}
+2013-11-23 Ian Lance Taylor <iant@google.com>
+
+ * go-gcc.cc (Gcc_backend::function_type): Add result_struct
+ parameter.
+
+2013-11-22 Andrew MacLeod <amacleod@redhat.com>
+
+ * go-gcc.cc: Add required include files from gimple.h.
+ * go-lang.c: Likewise
+
2013-11-18 Richard Sandiford <rdsandiford@googlemail.com>
* gofrontend/expressions.cc: Replace tree_low_cst (..., 0) with
#include "stor-layout.h"
#include "varasm.h"
#include "tree-iterator.h"
-#include "gimple.h"
+#include "basic-block.h"
+#include "gimple-expr.h"
#include "toplev.h"
#include "output.h"
#include "real.h"
function_type(const Btyped_identifier&,
const std::vector<Btyped_identifier>&,
const std::vector<Btyped_identifier>&,
+ Btype*,
const Location);
Btype*
Gcc_backend::function_type(const Btyped_identifier& receiver,
const std::vector<Btyped_identifier>& parameters,
const std::vector<Btyped_identifier>& results,
- Location location)
+ Btype* result_struct,
+ Location)
{
tree args = NULL_TREE;
tree* pp = &args;
result = results.front().btype->get_tree();
else
{
- result = make_node(RECORD_TYPE);
- tree field_trees = NULL_TREE;
- pp = &field_trees;
- for (std::vector<Btyped_identifier>::const_iterator p = results.begin();
- p != results.end();
- ++p)
- {
- const std::string name = (p->name.empty()
- ? "UNNAMED"
- : p->name);
- tree name_tree = get_identifier_from_string(name);
- tree field_type_tree = p->btype->get_tree();
- if (field_type_tree == error_mark_node)
- return this->error_type();
- gcc_assert(TYPE_SIZE(field_type_tree) != NULL_TREE);
- tree field = build_decl(location.gcc_location(), FIELD_DECL,
- name_tree, field_type_tree);
- DECL_CONTEXT(field) = result;
- *pp = field;
- pp = &DECL_CHAIN(field);
- }
- TYPE_FIELDS(result) = field_trees;
- layout_type(result);
+ gcc_assert(result_struct != NULL);
+ result = result_struct->get_tree();
}
if (result == error_mark_node)
return this->error_type();
#include "coretypes.h"
#include "opts.h"
#include "tree.h"
-#include "gimple.h"
+#include "basic-block.h"
+#include "gimple-expr.h"
#include "gimplify.h"
#include "stor-layout.h"
-#include "ggc.h"
#include "toplev.h"
#include "debug.h"
#include "options.h"
// is provided so that the names are available. This should return
// not the type of a Go function (which is a pointer to a struct)
// but the type of a C function pointer (which will be used as the
- // type of the first field of the struct).
+ // type of the first field of the struct). If there is more than
+ // one result, RESULT_STRUCT is a struct type to hold the results,
+ // and RESULTS may be ignored; if there are zero or one results,
+ // RESULT_STRUCT is NULL.
virtual Btype*
function_type(const Btyped_identifier& receiver,
const std::vector<Btyped_identifier>& parameters,
const std::vector<Btyped_identifier>& results,
+ Btype* result_struct,
Location location) = 0;
// Get a struct type.
// NAME is the name of the type, and the location is where the named
// type is defined. This function is also used for unnamed function
// types with multiple results, in which case the type has no name
- // and NAME will be empty. FOR_FUNCTION is true if this is for a Go
- // function type, which corresponds to a C/C++ pointer to function
- // type. The return value will later be passed as the first
- // parameter to set_placeholder_pointer_type or
+ // and NAME will be empty. FOR_FUNCTION is true if this is for a C
+ // pointer to function type. A Go func type is represented as a
+ // pointer to a struct, and the first field of the struct is a C
+ // pointer to function. The return value will later be passed as
+ // the first parameter to set_placeholder_pointer_type or
// set_placeholder_function_type.
virtual Btype*
placeholder_pointer_type(const std::string& name, Location,
#include "tree.h"
#include "stringpool.h"
#include "stor-layout.h"
-#include "gimple.h"
-#include "gimplify.h"
+#include "gimple-expr.h"
#include "tree-iterator.h"
#include "convert.h"
#include "real.h"
fndecl = TREE_OPERAND(fndecl, 0);
// Add a type cast in case the type of the function is a recursive
- // type which refers to itself.
- if (!DECL_P(fndecl) || !DECL_IS_BUILTIN(fndecl))
+ // type which refers to itself. We don't do this for an interface
+ // method because 1) an interface method never refers to itself, so
+ // we always have a function type here; 2) we pass an extra first
+ // argument to an interface method, so fnfield_type is not correct.
+ if ((!DECL_P(fndecl) || !DECL_IS_BUILTIN(fndecl)) && !is_interface_method)
fn = fold_convert_loc(location.gcc_location(), fnfield_type, fn);
// This is to support builtin math functions when using 80387 math.
#include "stringpool.h"
#include "stor-layout.h"
#include "varasm.h"
-#include "gimple.h"
+#include "gimple-expr.h"
#include "gimplify.h"
#include "tree-iterator.h"
#include "cgraph.h"
#include "toplev.h"
#include "intl.h"
#include "tree.h"
-#include "gimple.h"
-#include "gimplify.h"
#include "real.h"
#include "convert.h"
{
case TYPE_FUNCTION:
{
+ // A Go function type is a pointer to a struct type.
Location loc = this->function_type()->location();
- bt = gogo->backend()->placeholder_pointer_type("", loc, true);
+ bt = gogo->backend()->placeholder_pointer_type("", loc, false);
}
break;
case TYPE_FUNCTION:
{
Btype* bt = this->do_get_backend(gogo);
- if (!gogo->backend()->set_placeholder_function_type(placeholder, bt))
+ if (!gogo->backend()->set_placeholder_pointer_type(placeholder, bt))
go_assert(saw_errors());
}
break;
bloc);
gogo->start_block(bloc);
- if (this->struct_type() != NULL)
+ if (name != NULL && name->real_type()->named_type() != NULL)
+ this->write_named_hash(gogo, name, hash_fntype, equal_fntype);
+ else if (this->struct_type() != NULL)
this->struct_type()->write_hash_function(gogo, name, hash_fntype,
equal_fntype);
else if (this->array_type() != NULL)
false, bloc);
gogo->start_block(bloc);
- if (this->struct_type() != NULL)
+ if (name != NULL && name->real_type()->named_type() != NULL)
+ this->write_named_equal(gogo, name);
+ else if (this->struct_type() != NULL)
this->struct_type()->write_equal_function(gogo, name);
else if (this->array_type() != NULL)
this->array_type()->write_equal_function(gogo, name);
gogo->finish_function(bloc);
}
+// Write a hash function that simply calls the hash function for a
+// named type. This is used when one named type is defined as
+// another. This ensures that this case works when the other named
+// type is defined in another package and relies on calling hash
+// functions defined only in that package.
+
+void
+Type::write_named_hash(Gogo* gogo, Named_type* name,
+ Function_type* hash_fntype, Function_type* equal_fntype)
+{
+ Location bloc = Linemap::predeclared_location();
+
+ Named_type* base_type = name->real_type()->named_type();
+ go_assert(base_type != NULL);
+
+ // The pointer to the type we are going to hash. This is an
+ // unsafe.Pointer.
+ Named_object* key_arg = gogo->lookup("key", NULL);
+ go_assert(key_arg != NULL);
+
+ // The size of the type we are going to hash.
+ Named_object* keysz_arg = gogo->lookup("key_size", NULL);
+ go_assert(keysz_arg != NULL);
+
+ Named_object* hash_fn;
+ Named_object* equal_fn;
+ name->real_type()->type_functions(gogo, base_type, hash_fntype, equal_fntype,
+ &hash_fn, &equal_fn);
+
+ // Call the hash function for the base type.
+ Expression* key_ref = Expression::make_var_reference(key_arg, bloc);
+ Expression* keysz_ref = Expression::make_var_reference(keysz_arg, bloc);
+ Expression_list* args = new Expression_list();
+ args->push_back(key_ref);
+ args->push_back(keysz_ref);
+ Expression* func = Expression::make_func_reference(hash_fn, NULL, bloc);
+ Expression* call = Expression::make_call(func, args, false, bloc);
+
+ // Return the hash of the base type.
+ Expression_list* vals = new Expression_list();
+ vals->push_back(call);
+ Statement* s = Statement::make_return_statement(vals, bloc);
+ gogo->add_statement(s);
+}
+
+// Write an equality function that simply calls the equality function
+// for a named type. This is used when one named type is defined as
+// another. This ensures that this case works when the other named
+// type is defined in another package and relies on calling equality
+// functions defined only in that package.
+
+void
+Type::write_named_equal(Gogo* gogo, Named_type* name)
+{
+ Location bloc = Linemap::predeclared_location();
+
+ // The pointers to the types we are going to compare. These have
+ // type unsafe.Pointer.
+ Named_object* key1_arg = gogo->lookup("key1", NULL);
+ Named_object* key2_arg = gogo->lookup("key2", NULL);
+ go_assert(key1_arg != NULL && key2_arg != NULL);
+
+ Named_type* base_type = name->real_type()->named_type();
+ go_assert(base_type != NULL);
+
+ // Build temporaries with the base type.
+ Type* pt = Type::make_pointer_type(base_type);
+
+ Expression* ref = Expression::make_var_reference(key1_arg, bloc);
+ ref = Expression::make_cast(pt, ref, bloc);
+ Temporary_statement* p1 = Statement::make_temporary(pt, ref, bloc);
+ gogo->add_statement(p1);
+
+ ref = Expression::make_var_reference(key2_arg, bloc);
+ ref = Expression::make_cast(pt, ref, bloc);
+ Temporary_statement* p2 = Statement::make_temporary(pt, ref, bloc);
+ gogo->add_statement(p2);
+
+ // Compare the values for equality.
+ Expression* t1 = Expression::make_temporary_reference(p1, bloc);
+ t1 = Expression::make_unary(OPERATOR_MULT, t1, bloc);
+
+ Expression* t2 = Expression::make_temporary_reference(p2, bloc);
+ t2 = Expression::make_unary(OPERATOR_MULT, t2, bloc);
+
+ Expression* cond = Expression::make_binary(OPERATOR_EQEQ, t1, t2, bloc);
+
+ // Return the equality comparison.
+ Expression_list* vals = new Expression_list();
+ vals->push_back(cond);
+ Statement* s = Statement::make_return_statement(vals, bloc);
+ gogo->add_statement(s);
+}
+
// Return a composite literal for the type descriptor for a plain type
// of kind RUNTIME_TYPE_KIND named NAME.
return ret;
}
+// Hash result parameters.
+
+unsigned int
+Function_type::Results_hash::operator()(const Typed_identifier_list* t) const
+{
+ unsigned int hash = 0;
+ for (Typed_identifier_list::const_iterator p = t->begin();
+ p != t->end();
+ ++p)
+ {
+ hash <<= 2;
+ hash = Type::hash_string(p->name(), hash);
+ hash += p->type()->hash_for_method(NULL);
+ }
+ return hash;
+}
+
+// Compare result parameters so that can map identical result
+// parameters to a single struct type.
+
+bool
+Function_type::Results_equal::operator()(const Typed_identifier_list* a,
+ const Typed_identifier_list* b) const
+{
+ if (a->size() != b->size())
+ return false;
+ Typed_identifier_list::const_iterator pa = a->begin();
+ for (Typed_identifier_list::const_iterator pb = b->begin();
+ pb != b->end();
+ ++pa, ++pb)
+ {
+ if (pa->name() != pb->name()
+ || !Type::are_identical(pa->type(), pb->type(), true, NULL))
+ return false;
+ }
+ return true;
+}
+
+// Hash from results to a backend struct type.
+
+Function_type::Results_structs Function_type::results_structs;
+
// Get the backend representation for a function type.
Btype*
}
std::vector<Backend::Btyped_identifier> bresults;
+ Btype* bresult_struct = NULL;
if (this->results_ != NULL)
{
bresults.resize(this->results_->size());
size_t i = 0;
for (Typed_identifier_list::const_iterator p =
- this->results_->begin(); p != this->results_->end();
+ this->results_->begin();
+ p != this->results_->end();
++p, ++i)
{
bresults[i].name = Gogo::unpack_hidden_name(p->name());
bresults[i].location = p->location();
}
go_assert(i == bresults.size());
+
+ if (this->results_->size() > 1)
+ {
+ // Use the same results struct for all functions that
+ // return the same set of results. This is useful to
+ // unify calls to interface methods with other calls.
+ std::pair<Typed_identifier_list*, Btype*> val;
+ val.first = this->results_;
+ val.second = NULL;
+ std::pair<Results_structs::iterator, bool> ins =
+ Function_type::results_structs.insert(val);
+ if (ins.second)
+ {
+ // Build a new struct type.
+ Struct_field_list* sfl = new Struct_field_list;
+ for (Typed_identifier_list::const_iterator p =
+ this->results_->begin();
+ p != this->results_->end();
+ ++p)
+ {
+ Typed_identifier tid = *p;
+ if (tid.name().empty())
+ tid = Typed_identifier("UNNAMED", tid.type(),
+ tid.location());
+ sfl->push_back(Struct_field(tid));
+ }
+ Struct_type* st = Type::make_struct_type(sfl,
+ this->location());
+ ins.first->second = st->get_backend(gogo);
+ }
+ bresult_struct = ins.first->second;
+ }
}
this->fnbtype_ = gogo->backend()->function_type(breceiver, bparameters,
- bresults,
+ bresults, bresult_struct,
this->location());
}
return empty_interface_type;
}
-// Return the fields of a non-empty interface type. This is not
-// declared in types.h so that types.h doesn't have to #include
-// backend.h.
+// Return a pointer to the backend representation of the method table.
-static void
-get_backend_interface_fields(Gogo* gogo, Interface_type* type,
- bool use_placeholder,
- std::vector<Backend::Btyped_identifier>* bfields)
+Btype*
+Interface_type::get_backend_methods(Gogo* gogo)
{
- Location loc = type->location();
+ if (this->bmethods_ != NULL && !this->bmethods_is_placeholder_)
+ return this->bmethods_;
+
+ Location loc = this->location();
- std::vector<Backend::Btyped_identifier> mfields(type->methods()->size() + 1);
+ std::vector<Backend::Btyped_identifier>
+ mfields(this->all_methods_->size() + 1);
Type* pdt = Type::make_type_descriptor_ptr_type();
mfields[0].name = "__type_descriptor";
std::string last_name = "";
size_t i = 1;
- for (Typed_identifier_list::const_iterator p = type->methods()->begin();
- p != type->methods()->end();
+ for (Typed_identifier_list::const_iterator p = this->all_methods_->begin();
+ p != this->all_methods_->end();
++p, ++i)
{
// The type of the method in Go only includes the parameters.
ft->location());
mfields[i].name = Gogo::unpack_hidden_name(p->name());
- mfields[i].btype = (use_placeholder
- ? mft->get_backend_placeholder(gogo)
- : mft->get_backend(gogo));
+ mfields[i].btype = mft->get_backend_fntype(gogo);
mfields[i].location = loc;
+
// Sanity check: the names should be sorted.
go_assert(p->name() > last_name);
last_name = p->name();
}
- Btype* methods = gogo->backend()->struct_type(mfields);
+ Btype* st = gogo->backend()->struct_type(mfields);
+ Btype* ret = gogo->backend()->pointer_type(st);
+
+ if (this->bmethods_ != NULL && this->bmethods_is_placeholder_)
+ gogo->backend()->set_placeholder_pointer_type(this->bmethods_, ret);
+ this->bmethods_ = ret;
+ this->bmethods_is_placeholder_ = false;
+ return ret;
+}
+
+// Return a placeholder for the pointer to the backend methods table.
+
+Btype*
+Interface_type::get_backend_methods_placeholder(Gogo* gogo)
+{
+ if (this->bmethods_ == NULL)
+ {
+ Location loc = this->location();
+ this->bmethods_ = gogo->backend()->placeholder_pointer_type("", loc,
+ false);
+ this->bmethods_is_placeholder_ = true;
+ }
+ return this->bmethods_;
+}
+
+// Return the fields of a non-empty interface type. This is not
+// declared in types.h so that types.h doesn't have to #include
+// backend.h.
+
+static void
+get_backend_interface_fields(Gogo* gogo, Interface_type* type,
+ bool use_placeholder,
+ std::vector<Backend::Btyped_identifier>* bfields)
+{
+ Location loc = type->location();
bfields->resize(2);
(*bfields)[0].name = "__methods";
- (*bfields)[0].btype = gogo->backend()->pointer_type(methods);
+ (*bfields)[0].btype = (use_placeholder
+ ? type->get_backend_methods_placeholder(gogo)
+ : type->get_backend_methods(gogo));
(*bfields)[0].location = loc;
Type* vt = Type::make_pointer_type(Type::make_void_type());
void
Interface_type::finish_backend_methods(Gogo* gogo)
{
- if (!this->interface_type()->is_empty())
+ if (!this->is_empty())
{
const Typed_identifier_list* methods = this->methods();
if (methods != NULL)
++p)
p->type()->get_backend(gogo);
}
+
+ // Getting the backend methods now will set the placeholder
+ // pointer.
+ this->get_backend_methods(gogo);
}
}
if (this->seen_in_get_backend_)
{
this->is_circular_ = true;
- return gogo->backend()->circular_pointer_type(bt, true);
+ return gogo->backend()->circular_pointer_type(bt, false);
}
this->seen_in_get_backend_ = true;
bt1 = Type::get_named_base_btype(gogo, base);
this->seen_in_get_backend_ = false;
if (this->is_circular_)
- bt1 = gogo->backend()->circular_pointer_type(bt, true);
- if (!gogo->backend()->set_placeholder_function_type(bt, bt1))
+ bt1 = gogo->backend()->circular_pointer_type(bt, false);
+ if (!gogo->backend()->set_placeholder_pointer_type(bt, bt1))
bt = gogo->backend()->error_type();
return bt;
Function_type* equal_fntype, Named_object** hash_fn,
Named_object** equal_fn);
+ void
+ write_named_hash(Gogo*, Named_type*, Function_type* hash_fntype,
+ Function_type* equal_fntype);
+
+ void
+ write_named_equal(Gogo*, Named_type*);
+
// Build a composite literal for the uncommon type information.
Expression*
uncommon_type_constructor(Gogo*, Type* uncommon_type,
type_descriptor_params(Type*, const Typed_identifier*,
const Typed_identifier_list*);
+ // A mapping from a list of result types to a backend struct type.
+ class Results_hash
+ {
+ public:
+ unsigned int
+ operator()(const Typed_identifier_list*) const;
+ };
+
+ class Results_equal
+ {
+ public:
+ bool
+ operator()(const Typed_identifier_list*,
+ const Typed_identifier_list*) const;
+ };
+
+ typedef Unordered_map_hash(Typed_identifier_list*, Btype*,
+ Results_hash, Results_equal) Results_structs;
+
+ static Results_structs results_structs;
+
// The receiver name and type. This will be NULL for a normal
// function, non-NULL for a method.
Typed_identifier* receiver_;
Interface_type(Typed_identifier_list* methods, Location location)
: Type(TYPE_INTERFACE),
parse_methods_(methods), all_methods_(NULL), location_(location),
- interface_btype_(NULL), assume_identical_(NULL),
- methods_are_finalized_(false), seen_(false)
+ interface_btype_(NULL), bmethods_(NULL), assume_identical_(NULL),
+ methods_are_finalized_(false), bmethods_is_placeholder_(false),
+ seen_(false)
{ go_assert(methods == NULL || !methods->empty()); }
// The location where the interface type was defined.
static Btype*
get_backend_empty_interface_type(Gogo*);
+ // Get a pointer to the backend representation of the method table.
+ Btype*
+ get_backend_methods(Gogo*);
+
+ // Return a placeholder for the backend representation of the
+ // pointer to the method table.
+ Btype*
+ get_backend_methods_placeholder(Gogo*);
+
// Finish the backend representation of the method types.
void
finish_backend_methods(Gogo*);
Location location_;
// The backend representation of this type during backend conversion.
Btype* interface_btype_;
+ // The backend representation of the pointer to the method table.
+ Btype* bmethods_;
// A list of interface types assumed to be identical during
// interface comparison.
mutable Assume_identical* assume_identical_;
// Whether the methods have been finalized.
bool methods_are_finalized_;
+ // Whether the bmethods_ field is a placeholder.
+ bool bmethods_is_placeholder_;
// Used to avoid endless recursion in do_mangled_name.
mutable bool seen_;
};
#include "system.h"
#include "coretypes.h"
#include "tree.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "tree-ssa-loop.h"
#include "coretypes.h"
#include "diagnostic-core.h"
#include "tree.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimplify-me.h"
#include "system.h"
#include "coretypes.h"
#include "tree.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "tree-ssa-loop.h"
#include "system.h"
#include "coretypes.h"
#include "tree.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "tree-ssa-loop.h"
#include "system.h"
#include "coretypes.h"
#include "tree.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "tree-ssa-loop.h"
#include "coretypes.h"
#include "diagnostic-core.h"
#include "tree.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "tree-ssa-loop.h"
#include "system.h"
#include "coretypes.h"
#include "tree.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "system.h"
#include "coretypes.h"
#include "tree.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimplify.h"
#include "domwalk.h"
#include "sese.h"
#include "tree-ssa-propagate.h"
-#include "expr.h"
#ifdef HAVE_cloog
#include "expr.h"
#include "coretypes.h"
#include "diagnostic-core.h"
#include "tree.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "tree-cfg.h"
DEFGSSTRUCT(GSS_OMP, gimple_statement_omp, false)
DEFGSSTRUCT(GSS_OMP_CRITICAL, gimple_statement_omp_critical, false)
DEFGSSTRUCT(GSS_OMP_FOR, gimple_statement_omp_for, false)
-DEFGSSTRUCT(GSS_OMP_PARALLEL, gimple_statement_omp_parallel, false)
+DEFGSSTRUCT(GSS_OMP_PARALLEL_LAYOUT, gimple_statement_omp_parallel_layout, false)
DEFGSSTRUCT(GSS_OMP_TASK, gimple_statement_omp_task, false)
DEFGSSTRUCT(GSS_OMP_SECTIONS, gimple_statement_omp_sections, false)
-DEFGSSTRUCT(GSS_OMP_SINGLE, gimple_statement_omp_single, false)
+DEFGSSTRUCT(GSS_OMP_SINGLE_LAYOUT, gimple_statement_omp_single_layout, false)
DEFGSSTRUCT(GSS_OMP_CONTINUE, gimple_statement_omp_continue, false)
DEFGSSTRUCT(GSS_OMP_ATOMIC_LOAD, gimple_statement_omp_atomic_load, false)
-DEFGSSTRUCT(GSS_OMP_ATOMIC_STORE, gimple_statement_omp_atomic_store, false)
+DEFGSSTRUCT(GSS_OMP_ATOMIC_STORE_LAYOUT, gimple_statement_omp_atomic_store, false)
DEFGSSTRUCT(GSS_TRANSACTION, gimple_statement_transaction, false)
? stderr : dump_file);
}
-/* Try to group comparison and the following conditional jump INSN if
- they're already adjacent. This is to prevent scheduler from scheduling
- them apart. */
-
-static void
-try_group_insn (rtx insn)
-{
- unsigned int condreg1, condreg2;
- rtx cc_reg_1;
- rtx prev;
-
- if (!any_condjump_p (insn))
- return;
-
- targetm.fixed_condition_code_regs (&condreg1, &condreg2);
- cc_reg_1 = gen_rtx_REG (CCmode, condreg1);
- prev = prev_nonnote_nondebug_insn (insn);
- if (!reg_referenced_p (cc_reg_1, PATTERN (insn))
- || !prev
- || !modified_in_p (cc_reg_1, prev))
- return;
-
- /* Different microarchitectures support macro fusions for different
- combinations of insn pairs. */
- if (!targetm.sched.macro_fusion_pair_p
- || !targetm.sched.macro_fusion_pair_p (prev, insn))
- return;
-
- SCHED_GROUP_P (insn) = 1;
-}
-
-/* If the last cond jump and the cond register defining insn are consecutive
- before scheduling, we want them to be in a schedule group. This is good
- for performance on microarchitectures supporting macro-fusion. */
-
-static void
-group_insns_for_macro_fusion ()
-{
- basic_block bb;
-
- FOR_EACH_BB (bb)
- try_group_insn (BB_END (bb));
-}
-
/* Initialize some global state for the scheduler. This function works
with the common data shared between all the schedulers. It is called
from the scheduler specific initialization routine. */
sched_pressure = SCHED_PRESSURE_NONE;
if (sched_pressure != SCHED_PRESSURE_NONE)
- ira_setup_eliminable_regset (false);
+ ira_setup_eliminable_regset ();
/* Initialize SPEC_INFO. */
if (targetm.sched.set_sched_flags)
}
curr_state = xmalloc (dfa_state_size);
-
- /* Group compare and branch insns for macro-fusion. */
- if (targetm.sched.macro_fusion_p
- && targetm.sched.macro_fusion_p ())
- group_insns_for_macro_fusion ();
}
static void haifa_init_only_bb (basic_block, basic_block);
return NULL;
}
+/* Generic hook that takes a machine mode and returns an unsigned int 0. */
+unsigned int
+hook_uint_mode_0 (enum machine_mode m ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
/* Generic hook that takes three trees and returns the last one as is. */
tree
hook_tree_tree_tree_tree_3rd_identity (tree a ATTRIBUTE_UNUSED,
extern tree hook_tree_tree_int_treep_bool_null (tree, int, tree *, bool);
extern unsigned hook_uint_void_0 (void);
+extern unsigned int hook_uint_mode_0 (enum machine_mode);
extern bool default_can_output_mi_thunk_no_vcall (const_tree, HOST_WIDE_INT,
HOST_WIDE_INT, const_tree);
((tree) ((IS_ADHOC_LOC (LOC)) ? get_data_from_adhoc_loc (line_table, (LOC)) \
: NULL))
-#define input_line LOCATION_LINE (input_location)
-#define input_filename LOCATION_FILE (input_location)
#define in_system_header_at(LOC) \
((linemap_location_in_system_header_p (line_table, LOC)))
-#define in_system_header (in_system_header_at (input_location))
void dump_line_table_statistics (void);
#include "stor-layout.h"
#include "expr.h"
#include "optabs.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
/* The names of each internal function, indexed by function number. */
#include "system.h"
#include "coretypes.h"
#include "tree.h"
-#include "gimple.h"
+#include "gimple-fold.h"
+#include "gimple-expr.h"
#include "target.h"
#include "ipa-prop.h"
#include "bitmap.h"
reason = "not a tree_versionable_function";
else if (cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE)
reason = "insufficient body availability";
+ else if (lookup_attribute ("omp declare simd", DECL_ATTRIBUTES (node->decl)))
+ {
+ /* Ideally we should clone the SIMD clones themselves and create
+ vector copies of them, so IPA-cp and SIMD clones can happily
+ coexist, but that may not be worth the effort. */
+ reason = "function has SIMD clones";
+ }
if (reason && dump_file && !node->alias && !node->thunk.thunk_p)
fprintf (dump_file, "Function %s/%i is not versionable, reason: %s.\n",
#include "cgraph.h"
#include "expr.h"
#include "tree-pass.h"
-#include "ggc.h"
#include "pointer-set.h"
#include "target.h"
#include "hash-table.h"
#include "tree-pretty-print.h"
#include "ipa-utils.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-fold.h"
+#include "gimple-expr.h"
#include "gimple.h"
#include "ipa-inline.h"
#include "diagnostic.h"
return ndevirtualized ? TODO_remove_functions : 0;
}
-/* Gate for IPCP optimization. */
+/* Gate for speculative IPA devirtualization optimization. */
static bool
gate_ipa_devirt (void)
{
- return flag_devirtualize_speculatively && optimize;
+ return (flag_devirtualize
+ && flag_devirtualize_speculatively
+ && optimize);
}
namespace {
#include "params.h"
#include "tree-pass.h"
#include "coverage.h"
-#include "ggc.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimple-ssa.h"
}
- if (is_gimple_call (stmt))
+ if (is_gimple_call (stmt)
+ && !gimple_call_internal_p (stmt))
{
struct cgraph_edge *edge = cgraph_edge (node, stmt);
struct inline_edge_summary *es = inline_edge_summary (edge);
#include "intl.h"
#include "tree-pass.h"
#include "coverage.h"
-#include "ggc.h"
#include "rtl.h"
#include "bitmap.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-ssa.h"
#include "ipa-prop.h"
{
if (!can_inline_edge_p (e, true))
return true;
- if (!has_hot_call && cgraph_maybe_hot_edge_p (e))
+ if (!(*(bool *)has_hot_call) && cgraph_maybe_hot_edge_p (e))
*(bool *)has_hot_call = true;
}
return false;
#include "tree.h"
#include "cgraph.h"
#include "tree-pass.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
#include "gimple.h"
#include "gimple-iterator.h"
-#include "ggc.h"
#include "flags.h"
#include "target.h"
#include "tree-iterator.h"
#include "ipa-utils.h"
-#include "hash-table.h"
#include "profile.h"
#include "params.h"
#include "value-prof.h"
#include "system.h"
#include "coretypes.h"
#include "tree.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-fold.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "expr.h"
#include "stor-layout.h"
#include "gimplify-me.h"
#include "gimple-walk.h"
#include "langhooks.h"
-#include "ggc.h"
#include "target.h"
#include "ipa-prop.h"
#include "bitmap.h"
lhs = gimple_assign_lhs (stmt);
rhs = gimple_assign_rhs1 (stmt);
- if (!is_gimple_reg_type (rhs)
+ if (!is_gimple_reg_type (TREE_TYPE (rhs))
|| TREE_CODE (lhs) == BIT_FIELD_REF
|| contains_bitfld_component_ref_p (lhs))
break;
static void
ipa_add_new_function (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
{
- ipa_analyze_node (node);
+ if (cgraph_function_with_gimple_body_p (node))
+ ipa_analyze_node (node);
}
/* Register our cgraph hooks if they are not already there. */
/* Return a heap allocated vector containing types of formal parameters of
function type FNTYPE. */
-static inline vec<tree>
-get_vector_of_formal_parm_types (tree fntype)
+vec<tree>
+ipa_get_vector_of_formal_parm_types (tree fntype)
{
vec<tree> types;
int count = 0;
base_index field. */
void
-ipa_modify_formal_parameters (tree fndecl, ipa_parm_adjustment_vec adjustments,
- const char *synth_parm_prefix)
+ipa_modify_formal_parameters (tree fndecl, ipa_parm_adjustment_vec adjustments)
{
- vec<tree> oparms, otypes;
- tree orig_type, new_type = NULL;
- tree old_arg_types, t, new_arg_types = NULL;
- tree parm, *link = &DECL_ARGUMENTS (fndecl);
- int i, len = adjustments.length ();
- tree new_reversed = NULL;
- bool care_for_types, last_parm_void;
-
- if (!synth_parm_prefix)
- synth_parm_prefix = "SYNTH";
-
- oparms = ipa_get_vector_of_formal_parms (fndecl);
- orig_type = TREE_TYPE (fndecl);
- old_arg_types = TYPE_ARG_TYPES (orig_type);
+ vec<tree> oparms = ipa_get_vector_of_formal_parms (fndecl);
+ tree orig_type = TREE_TYPE (fndecl);
+ tree old_arg_types = TYPE_ARG_TYPES (orig_type);
/* The following test is an ugly hack, some functions simply don't have any
arguments in their type. This is probably a bug but well... */
- care_for_types = (old_arg_types != NULL_TREE);
+ bool care_for_types = (old_arg_types != NULL_TREE);
+ bool last_parm_void;
+ vec<tree> otypes;
if (care_for_types)
{
last_parm_void = (TREE_VALUE (tree_last (old_arg_types))
== void_type_node);
- otypes = get_vector_of_formal_parm_types (orig_type);
+ otypes = ipa_get_vector_of_formal_parm_types (orig_type);
if (last_parm_void)
gcc_assert (oparms.length () + 1 == otypes.length ());
else
otypes.create (0);
}
- for (i = 0; i < len; i++)
+ int len = adjustments.length ();
+ tree *link = &DECL_ARGUMENTS (fndecl);
+ tree new_arg_types = NULL;
+ for (int i = 0; i < len; i++)
{
struct ipa_parm_adjustment *adj;
gcc_assert (link);
adj = &adjustments[i];
- parm = oparms[adj->base_index];
+ tree parm;
+ if (adj->op == IPA_PARM_OP_NEW)
+ parm = NULL;
+ else
+ parm = oparms[adj->base_index];
adj->base = parm;
- if (adj->copy_param)
+ if (adj->op == IPA_PARM_OP_COPY)
{
if (care_for_types)
new_arg_types = tree_cons (NULL_TREE, otypes[adj->base_index],
*link = parm;
link = &DECL_CHAIN (parm);
}
- else if (!adj->remove_param)
+ else if (adj->op != IPA_PARM_OP_REMOVE)
{
tree new_parm;
tree ptype;
new_parm = build_decl (UNKNOWN_LOCATION, PARM_DECL, NULL_TREE,
ptype);
- DECL_NAME (new_parm) = create_tmp_var_name (synth_parm_prefix);
-
+ const char *prefix = adj->arg_prefix ? adj->arg_prefix : "SYNTH";
+ DECL_NAME (new_parm) = create_tmp_var_name (prefix);
DECL_ARTIFICIAL (new_parm) = 1;
DECL_ARG_TYPE (new_parm) = ptype;
DECL_CONTEXT (new_parm) = fndecl;
DECL_IGNORED_P (new_parm) = 1;
layout_decl (new_parm, 0);
- adj->base = parm;
- adj->reduction = new_parm;
+ if (adj->op == IPA_PARM_OP_NEW)
+ adj->base = NULL;
+ else
+ adj->base = parm;
+ adj->new_decl = new_parm;
*link = new_parm;
-
link = &DECL_CHAIN (new_parm);
}
}
*link = NULL_TREE;
+ tree new_reversed = NULL;
if (care_for_types)
{
new_reversed = nreverse (new_arg_types);
Exception is METHOD_TYPEs must have THIS argument.
When we are asked to remove it, we need to build new FUNCTION_TYPE
instead. */
+ tree new_type = NULL;
if (TREE_CODE (orig_type) != METHOD_TYPE
- || (adjustments[0].copy_param
+ || (adjustments[0].op == IPA_PARM_OP_COPY
&& adjustments[0].base_index == 0))
{
new_type = build_distinct_type_copy (orig_type);
/* This is a new type, not a copy of an old type. Need to reassociate
variants. We can handle everything except the main variant lazily. */
- t = TYPE_MAIN_VARIANT (orig_type);
+ tree t = TYPE_MAIN_VARIANT (orig_type);
if (orig_type != t)
{
TYPE_MAIN_VARIANT (new_type) = t;
adj = &adjustments[i];
- if (adj->copy_param)
+ if (adj->op == IPA_PARM_OP_COPY)
{
tree arg = gimple_call_arg (stmt, adj->base_index);
vargs.quick_push (arg);
}
- else if (!adj->remove_param)
+ else if (adj->op != IPA_PARM_OP_REMOVE)
{
tree expr, base, off;
location_t loc;
NULL, true, GSI_SAME_STMT);
vargs.quick_push (expr);
}
- if (!adj->copy_param && MAY_HAVE_DEBUG_STMTS)
+ if (adj->op != IPA_PARM_OP_COPY && MAY_HAVE_DEBUG_STMTS)
{
unsigned int ix;
tree ddecl = NULL_TREE, origin = DECL_ORIGIN (adj->base), arg;
free_dominance_info (CDI_DOMINATORS);
}
+/* If the expression *EXPR should be replaced by a reduction of a parameter, do
+ so. ADJUSTMENTS is a pointer to a vector of adjustments. CONVERT
+ specifies whether the function should care about type incompatibility the
+ current and new expressions. If it is false, the function will leave
+ incompatibility issues to the caller. Return true iff the expression
+ was modified. */
+
+bool
+ipa_modify_expr (tree *expr, bool convert,
+ ipa_parm_adjustment_vec adjustments)
+{
+ struct ipa_parm_adjustment *cand
+ = ipa_get_adjustment_candidate (&expr, &convert, adjustments, false);
+ if (!cand)
+ return false;
+
+ tree src;
+ if (cand->by_ref)
+ src = build_simple_mem_ref (cand->new_decl);
+ else
+ src = cand->new_decl;
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "About to replace expr ");
+ print_generic_expr (dump_file, *expr, 0);
+ fprintf (dump_file, " with ");
+ print_generic_expr (dump_file, src, 0);
+ fprintf (dump_file, "\n");
+ }
+
+ if (convert && !useless_type_conversion_p (TREE_TYPE (*expr), cand->type))
+ {
+ tree vce = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (*expr), src);
+ *expr = vce;
+ }
+ else
+ *expr = src;
+ return true;
+}
+
+/* If T is an SSA_NAME, return NULL if it is not a default def or
+ return its base variable if it is. If IGNORE_DEFAULT_DEF is true,
+ the base variable is always returned, regardless if it is a default
+ def. Return T if it is not an SSA_NAME. */
+
+static tree
+get_ssa_base_param (tree t, bool ignore_default_def)
+{
+ if (TREE_CODE (t) == SSA_NAME)
+ {
+ if (ignore_default_def || SSA_NAME_IS_DEFAULT_DEF (t))
+ return SSA_NAME_VAR (t);
+ else
+ return NULL_TREE;
+ }
+ return t;
+}
+
+/* Given an expression, return an adjustment entry specifying the
+ transformation to be done on EXPR. If no suitable adjustment entry
+ was found, returns NULL.
+
+ If IGNORE_DEFAULT_DEF is set, consider SSA_NAMEs which are not a
+ default def, otherwise bail on them.
+
+ If CONVERT is non-NULL, this function will set *CONVERT if the
+ expression provided is a component reference. ADJUSTMENTS is the
+ adjustments vector. */
+
+ipa_parm_adjustment *
+ipa_get_adjustment_candidate (tree **expr, bool *convert,
+ ipa_parm_adjustment_vec adjustments,
+ bool ignore_default_def)
+{
+ if (TREE_CODE (**expr) == BIT_FIELD_REF
+ || TREE_CODE (**expr) == IMAGPART_EXPR
+ || TREE_CODE (**expr) == REALPART_EXPR)
+ {
+ *expr = &TREE_OPERAND (**expr, 0);
+ if (convert)
+ *convert = true;
+ }
+
+ HOST_WIDE_INT offset, size, max_size;
+ tree base = get_ref_base_and_extent (**expr, &offset, &size, &max_size);
+ if (!base || size == -1 || max_size == -1)
+ return NULL;
+
+ if (TREE_CODE (base) == MEM_REF)
+ {
+ offset += mem_ref_offset (base).to_short_addr () * BITS_PER_UNIT;
+ base = TREE_OPERAND (base, 0);
+ }
+
+ base = get_ssa_base_param (base, ignore_default_def);
+ if (!base || TREE_CODE (base) != PARM_DECL)
+ return NULL;
+
+ struct ipa_parm_adjustment *cand = NULL;
+ unsigned int len = adjustments.length ();
+ for (unsigned i = 0; i < len; i++)
+ {
+ struct ipa_parm_adjustment *adj = &adjustments[i];
+
+ if (adj->base == base
+ && (adj->offset == offset || adj->op == IPA_PARM_OP_REMOVE))
+ {
+ cand = adj;
+ break;
+ }
+ }
+
+ if (!cand || cand->op == IPA_PARM_OP_COPY || cand->op == IPA_PARM_OP_REMOVE)
+ return NULL;
+ return cand;
+}
+
/* Return true iff BASE_INDEX is in ADJUSTMENTS more than once. */
static bool
struct ipa_parm_adjustment *n;
n = &inner[i];
- if (n->remove_param)
+ if (n->op == IPA_PARM_OP_REMOVE)
removals++;
else
- tmp.quick_push (*n);
+ {
+ /* FIXME: Handling of new arguments are not implemented yet. */
+ gcc_assert (n->op != IPA_PARM_OP_NEW);
+ tmp.quick_push (*n);
+ }
}
adjustments.create (outlen + removals);
struct ipa_parm_adjustment *in = &tmp[out->base_index];
memset (&r, 0, sizeof (r));
- gcc_assert (!in->remove_param);
- if (out->remove_param)
+ gcc_assert (in->op != IPA_PARM_OP_REMOVE);
+ if (out->op == IPA_PARM_OP_REMOVE)
{
if (!index_in_adjustments_multiple_times_p (in->base_index, tmp))
{
- r.remove_param = true;
+ r.op = IPA_PARM_OP_REMOVE;
adjustments.quick_push (r);
}
continue;
}
+ else
+ {
+ /* FIXME: Handling of new arguments are not implemented yet. */
+ gcc_assert (out->op != IPA_PARM_OP_NEW);
+ }
r.base_index = in->base_index;
r.type = out->type;
/* FIXME: Create nonlocal value too. */
- if (in->copy_param && out->copy_param)
- r.copy_param = true;
- else if (in->copy_param)
+ if (in->op == IPA_PARM_OP_COPY && out->op == IPA_PARM_OP_COPY)
+ r.op = IPA_PARM_OP_COPY;
+ else if (in->op == IPA_PARM_OP_COPY)
r.offset = out->offset;
- else if (out->copy_param)
+ else if (out->op == IPA_PARM_OP_COPY)
r.offset = in->offset;
else
r.offset = in->offset + out->offset;
{
struct ipa_parm_adjustment *n = &inner[i];
- if (n->remove_param)
+ if (n->op == IPA_PARM_OP_REMOVE)
adjustments.quick_push (*n);
}
fprintf (file, ", base: ");
print_generic_expr (file, adj->base, 0);
}
- if (adj->reduction)
+ if (adj->new_decl)
{
- fprintf (file, ", reduction: ");
- print_generic_expr (file, adj->reduction, 0);
+ fprintf (file, ", new_decl: ");
+ print_generic_expr (file, adj->new_decl, 0);
}
if (adj->new_ssa_base)
{
print_generic_expr (file, adj->new_ssa_base, 0);
}
- if (adj->copy_param)
+ if (adj->op == IPA_PARM_OP_COPY)
fprintf (file, ", copy_param");
- else if (adj->remove_param)
+ else if (adj->op == IPA_PARM_OP_REMOVE)
fprintf (file, ", remove_param");
else
fprintf (file, ", offset %li", (long) adj->offset);
extern alloc_pool ipcp_sources_pool;
extern alloc_pool ipcp_agg_lattice_pool;
+/* Operation to be performed for the parameter in ipa_parm_adjustment
+ below. */
+enum ipa_parm_op {
+ IPA_PARM_OP_NONE,
+
+ /* This describes a brand new parameter.
+
+ The field `type' should be set to the new type, `arg_prefix'
+ should be set to the string prefix for the new DECL_NAME, and
+ `new_decl' will ultimately hold the newly created argument. */
+ IPA_PARM_OP_NEW,
+
+ /* This new parameter is an unmodified parameter at index base_index. */
+ IPA_PARM_OP_COPY,
+
+ /* This adjustment describes a parameter that is about to be removed
+ completely. Most users will probably need to book keep those so that they
+ don't leave behinfd any non default def ssa names belonging to them. */
+ IPA_PARM_OP_REMOVE
+};
+
/* Structure to describe transformations of formal parameters and actual
arguments. Each instance describes one new parameter and they are meant to
be stored in a vector. Additionally, most users will probably want to store
arguments. */
tree alias_ptr_type;
- /* The new declaration when creating/replacing a parameter. Created by
- ipa_modify_formal_parameters, useful for functions modifying the body
- accordingly. */
- tree reduction;
+ /* The new declaration when creating/replacing a parameter. Created
+ by ipa_modify_formal_parameters, useful for functions modifying
+ the body accordingly. For brand new arguments, this is the newly
+ created argument. */
+ tree new_decl;
/* New declaration of a substitute variable that we may use to replace all
non-default-def ssa names when a parm decl is going away. */
is NULL), this is going to be its nonlocalized vars value. */
tree nonlocal_value;
+ /* This holds the prefix to be used for the new DECL_NAME. */
+ const char *arg_prefix;
+
/* Offset into the original parameter (for the cases when the new parameter
is a component of an original one). */
HOST_WIDE_INT offset;
- /* Zero based index of the original parameter this one is based on. (ATM
- there is no way to insert a new parameter out of the blue because there is
- no need but if it arises the code can be easily exteded to do so.) */
+ /* Zero based index of the original parameter this one is based on. */
int base_index;
- /* This new parameter is an unmodified parameter at index base_index. */
- unsigned copy_param : 1;
-
- /* This adjustment describes a parameter that is about to be removed
- completely. Most users will probably need to book keep those so that they
- don't leave behinfd any non default def ssa names belonging to them. */
- unsigned remove_param : 1;
+ /* Whether this parameter is a new parameter, a copy of an old one,
+ or one about to be removed. */
+ enum ipa_parm_op op;
/* The parameter is to be passed by reference. */
unsigned by_ref : 1;
typedef vec<ipa_parm_adjustment_t> ipa_parm_adjustment_vec;
vec<tree> ipa_get_vector_of_formal_parms (tree fndecl);
-void ipa_modify_formal_parameters (tree fndecl, ipa_parm_adjustment_vec,
- const char *);
+vec<tree> ipa_get_vector_of_formal_parm_types (tree fntype);
+void ipa_modify_formal_parameters (tree fndecl, ipa_parm_adjustment_vec);
void ipa_modify_call_arguments (struct cgraph_edge *, gimple,
ipa_parm_adjustment_vec);
ipa_parm_adjustment_vec ipa_combine_adjustments (ipa_parm_adjustment_vec,
struct ipa_jump_func *jfunc);
unsigned int ipcp_transform_function (struct cgraph_node *node);
void ipa_dump_param (FILE *, struct ipa_node_params *info, int i);
+bool ipa_modify_expr (tree *, bool, ipa_parm_adjustment_vec);
+ipa_parm_adjustment *ipa_get_adjustment_candidate (tree **, bool *,
+ ipa_parm_adjustment_vec,
+ bool);
/* From tree-sra.c: */
#include "tree.h"
#include "print-tree.h"
#include "calls.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimple-walk.h"
#include "tree-inline.h"
#include "tree-pass.h"
#include "langhooks.h"
-#include "pointer-set.h"
-#include "ggc.h"
#include "ipa-utils.h"
#include "flags.h"
#include "diagnostic.h"
#include "tm.h"
#include "tree.h"
#include "calls.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "tree-inline.h"
#include "tree-pass.h"
-#include "pointer-set.h"
#include "splay-tree.h"
-#include "ggc.h"
#include "ipa-utils.h"
#include "ipa-reference.h"
#include "flags.h"
#include "system.h"
#include "coretypes.h"
#include "tree.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "stringpool.h"
#include "expr.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "tree-inline.h"
#include "dumpfile.h"
#include "langhooks.h"
-#include "pointer-set.h"
#include "splay-tree.h"
-#include "ggc.h"
#include "ipa-utils.h"
#include "ipa-reference.h"
#include "flags.h"
#include "stringpool.h"
#include "cgraph.h"
#include "tree-pass.h"
-#include "gimple.h"
+#include "pointer-set.h"
+#include "gimple-expr.h"
#include "gimplify.h"
-#include "ggc.h"
#include "flags.h"
-#include "pointer-set.h"
#include "target.h"
#include "tree-iterator.h"
#include "ipa-utils.h"
hope calls to them will be devirtualized.
Again we remove them after inlining. In late optimization some
- devirtualization may happen, but it is not importnat since we won't inline
+ devirtualization may happen, but it is not important since we won't inline
the call. In theory early opts and IPA should work out all important cases.
- virtual clones needs bodies of their origins for later materialization;
by reachable symbols or origins of clones). The queue is represented
as linked list by AUX pointer terminated by 1.
- A the end we keep all reachable symbols. For symbols in boundary we always
+ At the end we keep all reachable symbols. For symbols in boundary we always
turn definition into a declaration, but we may keep function body around
based on body_needed_for_clonning
enqueue_node (cnode, &first, reachable);
}
}
+
+ }
+ /* If any reachable function has simd clones, mark them as
+ reachable as well. */
+ if (cnode->simd_clones)
+ {
+ cgraph_node *next;
+ for (next = cnode->simd_clones;
+ next;
+ next = next->simdclone->next_clone)
+ if (in_boundary_p
+ || !pointer_set_insert (reachable, next))
+ enqueue_node (next, &first, reachable);
}
}
/* When we see constructor of external variable, keep referred nodes in the
}
/* Generate and emit a static constructor or destructor. WHICH must
- be one of 'I' (for a constructor), 'D' (for a destructor), 'P'
- (for chp static vars constructor) or 'B' (for chkp static bounds
- constructor). BODY is a STATEMENT_LIST containing GENERIC
- statements. PRIORITY is the initialization priority for this
- constructor or destructor.
+ be one of 'I' (for a constructor) or 'D' (for a destructor). BODY
+ is a STATEMENT_LIST containing GENERIC statements. PRIORITY is the
+ initialization priority for this constructor or destructor.
FINAL specify whether the externally visible name for collect2 should
be produced. */
DECL_STATIC_CONSTRUCTOR (decl) = 1;
decl_init_priority_insert (decl, priority);
break;
- case 'P':
- DECL_STATIC_CONSTRUCTOR (decl) = 1;
- DECL_ATTRIBUTES (decl) = tree_cons (get_identifier ("chkp ctor"),
- NULL,
- NULL_TREE);
- decl_init_priority_insert (decl, priority);
- break;
- case 'B':
- DECL_STATIC_CONSTRUCTOR (decl) = 1;
- DECL_ATTRIBUTES (decl) = tree_cons (get_identifier ("bnd_legacy"),
- NULL,
- NULL_TREE);
- decl_init_priority_insert (decl, priority);
- break;
case 'D':
DECL_STATIC_DESTRUCTOR (decl) = 1;
decl_fini_priority_insert (decl, priority);
}
/* Generate and emit a static constructor or destructor. WHICH must
- be one of 'I' (for a constructor), 'D' (for a destructor), 'P'
- (for chkp static vars constructor) or 'B' (for chkp static bounds
- constructor). BODY is a STATEMENT_LIST containing GENERIC
- statements. PRIORITY is the initialization priority for this
- constructor or destructor. */
+ be one of 'I' (for a constructor) or 'D' (for a destructor). BODY
+ is a STATEMENT_LIST containing GENERIC statements. PRIORITY is the
+ initialization priority for this constructor or destructor. */
void
cgraph_build_static_cdtor (char which, tree body, int priority)
}
-/* Set up ELIMINABLE_REGSET, IRA_NO_ALLOC_REGS, and REGS_EVER_LIVE.
- If the function is called from IRA (not from the insn scheduler or
- RTL loop invariant motion), FROM_IRA_P is true. */
+/* Set up ELIMINABLE_REGSET, IRA_NO_ALLOC_REGS, and
+ REGS_EVER_LIVE. */
void
-ira_setup_eliminable_regset (bool from_ira_p)
+ira_setup_eliminable_regset (void)
{
#ifdef ELIMINABLE_REGS
int i;
if the stack pointer is moving. */
|| (flag_stack_check && STACK_CHECK_MOVING_SP)
|| crtl->accesses_prior_frames
- || crtl->stack_realign_needed
+ || (SUPPORTS_STACK_ALIGNMENT && crtl->stack_realign_needed)
/* We need a frame pointer for all Cilk Plus functions that use
Cilk keywords. */
|| (flag_enable_cilkplus && cfun->is_cilk_function)
|| targetm.frame_pointer_required ());
- if (from_ira_p && ira_use_lra_p)
- /* It can change FRAME_POINTER_NEEDED. We call it only from IRA
- because it is expensive. */
- lra_init_elimination ();
+ /* The chance that FRAME_POINTER_NEEDED is changed from inspecting
+ RTL is very small. So if we use frame pointer for RA and RTL
+ actually prevents this, we will spill pseudos assigned to the
+ frame pointer in LRA. */
if (frame_pointer_needed)
df_set_regs_ever_live (HARD_FRAME_POINTER_REGNUM, true);
{
rtx def_reg = DF_REF_REG (def);
rtx newreg = ira_create_new_reg (def_reg);
- if (validate_change (def_insn, DF_REF_LOC (def), newreg, 0))
+ if (validate_change (def_insn, DF_REF_REAL_LOC (def), newreg, 0))
{
unsigned nregno = REGNO (newreg);
emit_insn_before (gen_move_insn (def_reg, newreg), use_insn);
free_dominance_info (CDI_DOMINATORS);
}
-
-/* If insn is interesting for parameter range-splitting shring-wrapping
- preparation, i.e. it is a single set from a hard register to a pseudo, which
- is live at CALL_DOM, return the destination. Otherwise return NULL. */
+/* If SET pattern SET is an assignment from a hard register to a pseudo which
+ is live at CALL_DOM (if non-NULL, otherwise this check is omitted), return
+ the destination. Otherwise return NULL. */
static rtx
-interesting_dest_for_shprep (rtx insn, basic_block call_dom)
+interesting_dest_for_shprep_1 (rtx set, basic_block call_dom)
{
- rtx set = single_set (insn);
- if (!set)
- return NULL;
rtx src = SET_SRC (set);
rtx dest = SET_DEST (set);
if (!REG_P (src) || !HARD_REGISTER_P (src)
return dest;
}
+/* If insn is interesting for parameter range-splitting shring-wrapping
+ preparation, i.e. it is a single set from a hard register to a pseudo, which
+ is live at CALL_DOM (if non-NULL, otherwise this check is omitted), or a
+ parallel statement with only one such statement, return the destination.
+ Otherwise return NULL. */
+
+static rtx
+interesting_dest_for_shprep (rtx insn, basic_block call_dom)
+{
+ if (!INSN_P (insn))
+ return NULL;
+ rtx pat = PATTERN (insn);
+ if (GET_CODE (pat) == SET)
+ return interesting_dest_for_shprep_1 (pat, call_dom);
+
+ if (GET_CODE (pat) != PARALLEL)
+ return NULL;
+ rtx ret = NULL;
+ for (int i = 0; i < XVECLEN (pat, 0); i++)
+ {
+ rtx sub = XVECEXP (pat, 0, i);
+ if (GET_CODE (sub) == USE || GET_CODE (sub) == CLOBBER)
+ continue;
+ if (GET_CODE (sub) != SET
+ || side_effects_p (sub))
+ return NULL;
+ rtx dest = interesting_dest_for_shprep_1 (sub, call_dom);
+ if (dest && ret)
+ return NULL;
+ if (dest)
+ ret = dest;
+ }
+ return ret;
+}
+
/* Split live ranges of pseudos that are loaded from hard registers in the
first BB in a BB that dominates all non-sibling call if such a BB can be
found and is not in a loop. Return true if the function has made any
rtx newreg = NULL_RTX;
df_ref use, next;
- for (use = DF_REG_USE_CHAIN (REGNO(dest)); use; use = next)
+ for (use = DF_REG_USE_CHAIN (REGNO (dest)); use; use = next)
{
rtx uin = DF_REF_INSN (use);
next = DF_REF_NEXT_REG (use);
{
if (!newreg)
newreg = ira_create_new_reg (dest);
- validate_change (uin, DF_REF_LOC (use), newreg, true);
+ validate_change (uin, DF_REF_REAL_LOC (use), newreg, true);
}
}
find_moveable_pseudos ();
max_regno_before_ira = max_reg_num ();
- ira_setup_eliminable_regset (true);
+ ira_setup_eliminable_regset ();
ira_overall_cost = ira_reg_cost = ira_mem_cost = 0;
ira_load_cost = ira_store_cost = ira_shuffle_cost = 0;
extern void ira_init_once (void);
extern void ira_init (void);
extern void ira_finish_once (void);
-extern void ira_setup_eliminable_regset (bool);
+extern void ira_setup_eliminable_regset (void);
extern rtx ira_eliminate_regs (rtx, enum machine_mode);
extern void ira_set_pseudo_classes (bool, FILE *);
extern void ira_implicitly_set_insn_hard_regs (HARD_REG_SET *);
+2013-11-22 Andrew MacLeod <amacleod@redhat.com>
+
+ * java-gimplify.c: Add required include files from gimple.h.
+
+2013-11-22 David Malcolm <dmalcolm@redhat.com>
+
+ * class.c (maybe_layout_super_class): Update comment.
+ * decl.c (java_add_stmt): Remove use of input_filename macro.
+ * jcf-parse.c (set_source_filename): Remove use of
+ input_filename macro.
+ (parse_class_file): Remove use of input_line and input_filename
+ macros.
+ (java_parse_file): Remove use of input_filename macro.
+
2013-11-18 Richard Sandiford <rdsandiford@googlemail.com>
* class.c, expr.c: Replace tree_low_cst (..., 0) with tree_to_shwi
}
/* safe_layout_class just makes sure that we can load a class without
- disrupting the current_class, input_file, input_line, etc, information
+ disrupting the current_class, input_location, etc, information
about the class processed currently. */
void
tree stmts = current_binding_level->stmts;
tree_stmt_iterator i;
- if (input_filename)
+ if (LOCATION_FILE (input_location))
walk_tree (&new_stmt, set_input_location, NULL, NULL);
if (stmts == NULL)
#include "tree.h"
#include "java-tree.h"
#include "dumpfile.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimplify.h"
{
tree sfname_id = get_name_constant (jcf, index);
const char *sfname = IDENTIFIER_POINTER (sfname_id);
- const char *old_filename = input_filename;
+ const char *old_filename = LOCATION_FILE (input_location);
int new_len = IDENTIFIER_LENGTH (sfname_id);
if (old_filename != NULL)
{
int old_len = strlen (old_filename);
- /* Use the current input_filename (derived from the class name)
- if it has a directory prefix, but otherwise matches sfname. */
+ /* Use the filename from current input_location (derived from the
+ class name) if it has a directory prefix, but otherwise matches
+ sfname. */
if (old_len > new_len
&& filename_cmp (sfname, old_filename + old_len - new_len) == 0
&& (old_filename[old_len - new_len - 1] == '/'
linemap_add (line_table, LC_ENTER, 0, loc.file, loc.line);
}
file_start_location = input_location;
- (*debug_hooks->start_source_file) (input_line, input_filename);
+ (*debug_hooks->start_source_file) (LOCATION_LINE (input_location),
+ LOCATION_FILE (input_location));
java_mark_class_local (current_class);
for (ptr += 2; --i >= 0; ptr += 4)
{
int line = GET_u2 (ptr);
- /* Set initial input_line to smallest linenumber.
+ /* Set initial line of input_location to smallest
+ * linenumber.
* Needs to be set before init_function_start. */
if (min_line == 0 || line < min_line)
min_line = line;
int avail = 2000;
finput = fopen (main_input_filename, "r");
if (finput == NULL)
- fatal_error ("can%'t open %s: %m", input_filename);
+ fatal_error ("can%'t open %s: %m", LOCATION_FILE (input_location));
list = XNEWVEC (char, avail);
next = list;
for (;;)
if (count == 0)
{
if (! feof (finput))
- fatal_error ("error closing %s: %m", input_filename);
+ fatal_error ("error closing %s: %m",
+ LOCATION_FILE (input_location));
*next = '\0';
break;
}
#include "stringpool.h"
#include "attribs.h"
#include "tree-inline.h"
-#include "gimple.h"
#include "gimplify.h"
#include "rtl.h"
#include "insn-config.h"
#include "langhooks.h"
#include "target.h"
#include "langhooks-def.h"
-#include "ggc.h"
#include "diagnostic.h"
#include "tree-diagnostic.h"
#include "cgraph.h"
bitmap_initialize (&LOOP_DATA (loop)->regs_ref, ®_obstack);
bitmap_initialize (&LOOP_DATA (loop)->regs_live, ®_obstack);
}
- ira_setup_eliminable_regset (false);
+ ira_setup_eliminable_regset ();
bitmap_initialize (&curr_regs_live, ®_obstack);
FOR_EACH_BB (bb)
{
if (nunroll > (unsigned) PARAM_VALUE (PARAM_MAX_UNROLL_TIMES))
nunroll = PARAM_VALUE (PARAM_MAX_UNROLL_TIMES);
+ if (targetm.loop_unroll_adjust)
+ nunroll = targetm.loop_unroll_adjust (nunroll, loop);
+
/* Skip big loops. */
if (nunroll <= 1)
{
/* If we have decided to substitute X with another value, return that
value, otherwise return X. */
static rtx
-get_equiv_substitution (rtx x)
+get_equiv (rtx x)
{
int regno;
rtx res;
gcc_unreachable ();
}
+/* If we have decided to substitute X with the equivalent value,
+ return that value after elimination for INSN, otherwise return
+ X. */
+static rtx
+get_equiv_with_elimination (rtx x, rtx insn)
+{
+ rtx res = get_equiv (x);
+
+ if (x == res || CONSTANT_P (res))
+ return res;
+ return lra_eliminate_regs_1 (insn, res, GET_MODE (res), false, false, true);
+}
+
/* Set up curr_operand_mode. */
static void
init_curr_operand_mode (void)
{
regno = REGNO (reg);
rclass = get_reg_class (regno);
- if ((*loc = get_equiv_substitution (reg)) != reg)
+ if ((*loc = get_equiv_with_elimination (reg, curr_insn)) != reg)
{
if (lra_dump_file != NULL)
{
int const_to_mem = 0;
bool no_regs_p;
+ /* Never do output reload of stack pointer. It makes
+ impossible to do elimination when SP is changed in
+ RTL. */
+ if (op == stack_pointer_rtx && ! frame_pointer_needed
+ && curr_static_id->operand[nop].type != OP_IN)
+ goto fail;
+
/* If this alternative asks for a specific reg class, see if there
is at least one allocatable register in that class. */
no_regs_p
else
{
base_reg = *base_term;
- new_base_reg = get_equiv_substitution (base_reg);
+ new_base_reg = get_equiv_with_elimination (base_reg, curr_insn);
}
index_term = strip_subreg (ad->index_term);
if (index_term == NULL)
else
{
index_reg = *index_term;
- new_index_reg = get_equiv_substitution (index_reg);
+ new_index_reg = get_equiv_with_elimination (index_reg, curr_insn);
}
if (base_reg == new_base_reg && index_reg == new_index_reg)
return false;
if (GET_CODE (old) == SUBREG)
old = SUBREG_REG (old);
- subst = get_equiv_substitution (old);
+ subst = get_equiv_with_elimination (old, curr_insn);
if (subst != old)
{
subst = copy_rtx (subst);
if (INSN_CODE (curr_insn) >= 0
&& (p = get_insn_name (INSN_CODE (curr_insn))) != NULL)
fprintf (lra_dump_file, " {%s}", p);
+ if (curr_id->sp_offset != 0)
+ fprintf (lra_dump_file, " (sp_off=%" HOST_WIDE_INT_PRINT "d)",
+ curr_id->sp_offset);
fprintf (lra_dump_file, "\n");
}
if (code == SUBREG)
{
reg = SUBREG_REG (x);
- if ((subst = get_equiv_substitution (reg)) != reg
+ if ((subst = get_equiv_with_elimination (reg, curr_insn)) != reg
&& GET_MODE (subst) == VOIDmode)
{
/* We cannot reload debug location. Simplify subreg here
return true;
}
}
- if (code == REG && (subst = get_equiv_substitution (x)) != x)
+ if (code == REG && (subst = get_equiv_with_elimination (x, curr_insn)) != x)
{
*loc = subst;
return true;
if (!REG_P (loc))
return NULL_RTX;
- rtx subst = get_equiv_substitution (loc);
+ rtx subst = get_equiv_with_elimination (loc, curr_insn);
if (subst != loc)
return subst;
lra_risky_transformations_p = false;
new_insn_uid_start = get_max_uid ();
new_regno_start = first_p ? lra_constraint_new_regno_start : max_reg_num ();
+ /* Mark used hard regs for target stack size calulations. */
+ for (i = FIRST_PSEUDO_REGISTER; i < new_regno_start; i++)
+ if (lra_reg_info[i].nrefs != 0
+ && (hard_regno = lra_get_regno_hard_regno (i)) >= 0)
+ {
+ int j, nregs;
+
+ nregs = hard_regno_nregs[hard_regno][lra_reg_info[i].biggest_mode];
+ for (j = 0; j < nregs; j++)
+ df_set_regs_ever_live (hard_regno + j, true);
+ }
+ /* Do elimination before the equivalence processing as we can spill
+ some pseudos during elimination. */
+ lra_eliminate (false, first_p);
bitmap_initialize (&equiv_insn_bitmap, ®_obstack);
for (i = FIRST_PSEUDO_REGISTER; i < new_regno_start; i++)
if (lra_reg_info[i].nrefs != 0)
{
ira_reg_equiv[i].profitable_p = true;
reg = regno_reg_rtx[i];
- if ((hard_regno = lra_get_regno_hard_regno (i)) >= 0)
- {
- int j, nregs;
-
- nregs = hard_regno_nregs[hard_regno][lra_reg_info[i].biggest_mode];
- for (j = 0; j < nregs; j++)
- df_set_regs_ever_live (hard_regno + j, true);
- }
- else if ((x = get_equiv_substitution (reg)) != reg)
+ if (lra_get_regno_hard_regno (i) < 0 && (x = get_equiv (reg)) != reg)
{
bool pseudo_p = contains_reg_p (x, false, false);
ira_reg_equiv[i].defined_p = false;
if (contains_reg_p (x, false, true))
ira_reg_equiv[i].profitable_p = false;
- if (get_equiv_substitution (reg) != reg)
+ if (get_equiv (reg) != reg)
bitmap_ior_into (&equiv_insn_bitmap, &lra_reg_info[i].insn_bitmap);
}
}
substituted by their equivalences. */
EXECUTE_IF_SET_IN_BITMAP (&equiv_insn_bitmap, 0, uid, bi)
lra_push_insn_by_uid (uid);
- lra_eliminate (false);
min_len = lra_insn_stack_length ();
new_insns_num = 0;
last_bb = NULL;
if (GET_CODE (dest_reg) == SUBREG)
dest_reg = SUBREG_REG (dest_reg);
if ((REG_P (dest_reg)
- && (x = get_equiv_substitution (dest_reg)) != dest_reg
+ && (x = get_equiv (dest_reg)) != dest_reg
/* Remove insns which set up a pseudo whose value
can not be changed. Such insns might be not in
init_insns because we don't update equiv data
|| in_list_p (curr_insn,
ira_reg_equiv
[REGNO (dest_reg)].init_insns)))
- || (((x = get_equiv_substitution (SET_SRC (set)))
- != SET_SRC (set))
+ || (((x = get_equiv (SET_SRC (set))) != SET_SRC (set))
&& in_list_p (curr_insn,
ira_reg_equiv
[REGNO (SET_SRC (set))].init_insns)))
}
/* Scan X and replace any eliminable registers (such as fp) with a
- replacement (such as sp) if SUBST_P, plus an offset. The offset is
+ replacement (such as sp) if SUBST_P, plus an offset. The offset is
a change in the offset between the eliminable register and its
substitution if UPDATE_P, or the full offset if FULL_P, or
- otherwise zero.
+ otherwise zero. If FULL_P, we also use the SP offsets for
+ elimination to SP.
MEM_MODE is the mode of an enclosing MEM. We need this to know how
much to adjust a register for, e.g., PRE_DEC. Also, if we are
outside a MEM. In addition, we need to record the fact that a
hard register is referenced outside a MEM.
- Alternatively, INSN may be a note (an EXPR_LIST or INSN_LIST).
- That's used when we eliminate in expressions stored in notes. */
+ If we make full substitution to SP for non-null INSN, add the insn
+ sp offset. */
rtx
-lra_eliminate_regs_1 (rtx x, enum machine_mode mem_mode,
+lra_eliminate_regs_1 (rtx insn, rtx x, enum machine_mode mem_mode,
bool subst_p, bool update_p, bool full_p)
{
enum rtx_code code = GET_CODE (x);
const char *fmt;
int copied = 0;
+ gcc_assert (!update_p || !full_p);
if (! current_function_decl)
return x;
if (update_p)
return plus_constant (Pmode, to, ep->offset - ep->previous_offset);
else if (full_p)
- return plus_constant (Pmode, to, ep->offset);
+ return plus_constant (Pmode, to,
+ ep->offset
+ - (insn != NULL_RTX
+ && ep->to_rtx == stack_pointer_rtx
+ ? lra_get_insn_recog_data (insn)->sp_offset
+ : 0));
else
return to;
}
offset = (update_p
? ep->offset - ep->previous_offset : ep->offset);
+ if (full_p && insn != NULL_RTX && ep->to_rtx == stack_pointer_rtx)
+ offset -= lra_get_insn_recog_data (insn)->sp_offset;
if (CONST_INT_P (XEXP (x, 1))
&& INTVAL (XEXP (x, 1)) == -offset)
return to;
an address operand of a load-address insn. */
{
- rtx new0 = lra_eliminate_regs_1 (XEXP (x, 0), mem_mode,
+ rtx new0 = lra_eliminate_regs_1 (insn, XEXP (x, 0), mem_mode,
subst_p, update_p, full_p);
- rtx new1 = lra_eliminate_regs_1 (XEXP (x, 1), mem_mode,
+ rtx new1 = lra_eliminate_regs_1 (insn, XEXP (x, 1), mem_mode,
subst_p, update_p, full_p);
if (new0 != XEXP (x, 0) || new1 != XEXP (x, 1))
(ep->offset - ep->previous_offset)
* INTVAL (XEXP (x, 1)));
else if (full_p)
- return
- plus_constant (Pmode,
- gen_rtx_MULT (Pmode, to, XEXP (x, 1)),
- ep->offset * INTVAL (XEXP (x, 1)));
+ {
+ HOST_WIDE_INT offset = ep->offset;
+
+ if (insn != NULL_RTX && ep->to_rtx == stack_pointer_rtx)
+ offset -= lra_get_insn_recog_data (insn)->sp_offset;
+ return
+ plus_constant (Pmode,
+ gen_rtx_MULT (Pmode, to, XEXP (x, 1)),
+ offset * INTVAL (XEXP (x, 1)));
+ }
else
return gen_rtx_MULT (Pmode, to, XEXP (x, 1));
}
case GE: case GT: case GEU: case GTU:
case LE: case LT: case LEU: case LTU:
{
- rtx new0 = lra_eliminate_regs_1 (XEXP (x, 0), mem_mode,
+ rtx new0 = lra_eliminate_regs_1 (insn, XEXP (x, 0), mem_mode,
subst_p, update_p, full_p);
rtx new1 = XEXP (x, 1)
- ? lra_eliminate_regs_1 (XEXP (x, 1), mem_mode,
+ ? lra_eliminate_regs_1 (insn, XEXP (x, 1), mem_mode,
subst_p, update_p, full_p) : 0;
if (new0 != XEXP (x, 0) || new1 != XEXP (x, 1))
eliminate it. */
if (XEXP (x, 0))
{
- new_rtx = lra_eliminate_regs_1 (XEXP (x, 0), mem_mode,
+ new_rtx = lra_eliminate_regs_1 (insn, XEXP (x, 0), mem_mode,
subst_p, update_p, full_p);
if (new_rtx != XEXP (x, 0))
{
REG_DEAD note for the stack or frame pointer. */
if (REG_NOTE_KIND (x) == REG_DEAD)
return (XEXP (x, 1)
- ? lra_eliminate_regs_1 (XEXP (x, 1), mem_mode,
+ ? lra_eliminate_regs_1 (insn, XEXP (x, 1), mem_mode,
subst_p, update_p, full_p)
: NULL_RTX);
strictly needed, but it simplifies the code. */
if (XEXP (x, 1))
{
- new_rtx = lra_eliminate_regs_1 (XEXP (x, 1), mem_mode,
+ new_rtx = lra_eliminate_regs_1 (insn, XEXP (x, 1), mem_mode,
subst_p, update_p, full_p);
if (new_rtx != XEXP (x, 1))
return
if (GET_CODE (XEXP (x, 1)) == PLUS
&& XEXP (XEXP (x, 1), 0) == XEXP (x, 0))
{
- rtx new_rtx = lra_eliminate_regs_1 (XEXP (XEXP (x, 1), 1), mem_mode,
+ rtx new_rtx = lra_eliminate_regs_1 (insn, XEXP (XEXP (x, 1), 1),
+ mem_mode,
subst_p, update_p, full_p);
if (new_rtx != XEXP (XEXP (x, 1), 1))
case POPCOUNT:
case PARITY:
case BSWAP:
- new_rtx = lra_eliminate_regs_1 (XEXP (x, 0), mem_mode,
+ new_rtx = lra_eliminate_regs_1 (insn, XEXP (x, 0), mem_mode,
subst_p, update_p, full_p);
if (new_rtx != XEXP (x, 0))
return gen_rtx_fmt_e (code, GET_MODE (x), new_rtx);
return x;
case SUBREG:
- new_rtx = lra_eliminate_regs_1 (SUBREG_REG (x), mem_mode,
+ new_rtx = lra_eliminate_regs_1 (insn, SUBREG_REG (x), mem_mode,
subst_p, update_p, full_p);
if (new_rtx != SUBREG_REG (x))
return
replace_equiv_address_nv
(x,
- lra_eliminate_regs_1 (XEXP (x, 0), GET_MODE (x),
+ lra_eliminate_regs_1 (insn, XEXP (x, 0), GET_MODE (x),
subst_p, update_p, full_p));
case USE:
/* Handle insn_list USE that a call to a pure function may generate. */
- new_rtx = lra_eliminate_regs_1 (XEXP (x, 0), VOIDmode,
+ new_rtx = lra_eliminate_regs_1 (insn, XEXP (x, 0), VOIDmode,
subst_p, update_p, full_p);
if (new_rtx != XEXP (x, 0))
return gen_rtx_USE (GET_MODE (x), new_rtx);
{
if (*fmt == 'e')
{
- new_rtx = lra_eliminate_regs_1 (XEXP (x, i), mem_mode,
+ new_rtx = lra_eliminate_regs_1 (insn, XEXP (x, i), mem_mode,
subst_p, update_p, full_p);
if (new_rtx != XEXP (x, i) && ! copied)
{
int copied_vec = 0;
for (j = 0; j < XVECLEN (x, i); j++)
{
- new_rtx = lra_eliminate_regs_1 (XVECEXP (x, i, j), mem_mode,
+ new_rtx = lra_eliminate_regs_1 (insn, XVECEXP (x, i, j), mem_mode,
subst_p, update_p, full_p);
if (new_rtx != XVECEXP (x, i, j) && ! copied_vec)
{
lra_eliminate_regs (rtx x, enum machine_mode mem_mode,
rtx insn ATTRIBUTE_UNUSED)
{
- return lra_eliminate_regs_1 (x, mem_mode, true, false, true);
+ return lra_eliminate_regs_1 (NULL_RTX, x, mem_mode, true, false, true);
}
+/* Stack pointer offset before the current insn relative to one at the
+ func start. RTL insns can change SP explicitly. We keep the
+ changes from one insn to another through this variable. */
+static HOST_WIDE_INT curr_sp_change;
+
/* Scan rtx X for references to elimination source or target registers
in contexts that would prevent the elimination from happening.
Update the table of eliminables to reflect the changed state.
MEM_MODE is the mode of an enclosing MEM rtx, or VOIDmode if not
within a MEM. */
static void
-mark_not_eliminable (rtx x)
+mark_not_eliminable (rtx x, enum machine_mode mem_mode)
{
enum rtx_code code = GET_CODE (x);
struct elim_table *ep;
case POST_DEC:
case POST_MODIFY:
case PRE_MODIFY:
- if (REG_P (XEXP (x, 0)) && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER)
- /* If we modify the source of an elimination rule, disable
- it. Do the same if it is the source and not the hard frame
- register. */
- for (ep = reg_eliminate;
- ep < ®_eliminate[NUM_ELIMINABLE_REGS];
+ if (XEXP (x, 0) == stack_pointer_rtx
+ && ((code != PRE_MODIFY && code != POST_MODIFY)
+ || (GET_CODE (XEXP (x, 1)) == PLUS
+ && XEXP (x, 0) == XEXP (XEXP (x, 1), 0)
+ && CONST_INT_P (XEXP (XEXP (x, 1), 1)))))
+ {
+ int size = GET_MODE_SIZE (mem_mode);
+
+#ifdef PUSH_ROUNDING
+ /* If more bytes than MEM_MODE are pushed, account for
+ them. */
+ size = PUSH_ROUNDING (size);
+#endif
+ if (code == PRE_DEC || code == POST_DEC)
+ curr_sp_change -= size;
+ else if (code == PRE_INC || code == POST_INC)
+ curr_sp_change += size;
+ else if (code == PRE_MODIFY || code == POST_MODIFY)
+ curr_sp_change += INTVAL (XEXP (XEXP (x, 1), 1));
+ }
+ else if (REG_P (XEXP (x, 0))
+ && REGNO (XEXP (x, 0)) >= FIRST_PSEUDO_REGISTER)
+ {
+ /* If we modify the source of an elimination rule, disable
+ it. Do the same if it is the destination and not the
+ hard frame register. */
+ for (ep = reg_eliminate;
+ ep < ®_eliminate[NUM_ELIMINABLE_REGS];
ep++)
- if (ep->from_rtx == XEXP (x, 0)
- || (ep->to_rtx == XEXP (x, 0)
- && ep->to_rtx != hard_frame_pointer_rtx))
- setup_can_eliminate (ep, false);
+ if (ep->from_rtx == XEXP (x, 0)
+ || (ep->to_rtx == XEXP (x, 0)
+ && ep->to_rtx != hard_frame_pointer_rtx))
+ setup_can_eliminate (ep, false);
+ }
return;
case USE:
return;
case SET:
- /* Check for setting a hard register that we know about. */
- if (REG_P (SET_DEST (x)) && REGNO (SET_DEST (x)) < FIRST_PSEUDO_REGISTER)
+ if (SET_DEST (x) == stack_pointer_rtx
+ && GET_CODE (SET_SRC (x)) == PLUS
+ && XEXP (SET_SRC (x), 0) == SET_DEST (x)
+ && CONST_INT_P (XEXP (SET_SRC (x), 1)))
+ {
+ curr_sp_change += INTVAL (XEXP (SET_SRC (x), 1));
+ return;
+ }
+ if (! REG_P (SET_DEST (x))
+ || REGNO (SET_DEST (x)) >= FIRST_PSEUDO_REGISTER)
+ mark_not_eliminable (SET_DEST (x), mem_mode);
+ else
{
/* See if this is setting the replacement hard register for
an elimination.
-
+
If DEST is the hard frame pointer, we do nothing because
we assume that all assignments to the frame pointer are
for non-local gotos and are being done at a time when
even a fake frame pointer) with either the real frame
pointer or the stack pointer. Assignments to the hard
frame pointer must not prevent this elimination. */
-
for (ep = reg_eliminate;
ep < ®_eliminate[NUM_ELIMINABLE_REGS];
ep++)
if (ep->to_rtx == SET_DEST (x)
- && SET_DEST (x) != hard_frame_pointer_rtx
- && (! (SUPPORTS_STACK_ALIGNMENT && stack_realign_fp
- && REGNO (ep->to_rtx) == STACK_POINTER_REGNUM)
- || GET_CODE (SET_SRC (x)) != PLUS
- || XEXP (SET_SRC (x), 0) != SET_DEST (x)
- || ! CONST_INT_P (XEXP (SET_SRC (x), 1))))
+ && SET_DEST (x) != hard_frame_pointer_rtx)
setup_can_eliminate (ep, false);
}
+
+ mark_not_eliminable (SET_SRC (x), mem_mode);
+ return;
- mark_not_eliminable (SET_DEST (x));
- mark_not_eliminable (SET_SRC (x));
+ case MEM:
+ /* Our only special processing is to pass the mode of the MEM to
+ our recursive call. */
+ mark_not_eliminable (XEXP (x, 0), GET_MODE (x));
return;
default:
for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++)
{
if (*fmt == 'e')
- mark_not_eliminable (XEXP (x, i));
+ mark_not_eliminable (XEXP (x, i), mem_mode);
else if (*fmt == 'E')
for (j = 0; j < XVECLEN (x, i); j++)
- mark_not_eliminable (XVECEXP (x, i, j));
+ mark_not_eliminable (XVECEXP (x, i, j), mem_mode);
}
}
delete the insn as dead it if it is setting an eliminable register.
If REPLACE_P is false, just update the offsets while keeping the
- base register the same. Attach the note about used elimination for
+ base register the same. If FIRST_P, use the sp offset for
+ elimination to sp. Attach the note about used elimination for
insns setting frame pointer to update elimination easy (without
parsing already generated elimination insns to find offset
previously used) in future. */
static void
-eliminate_regs_in_insn (rtx insn, bool replace_p)
+eliminate_regs_in_insn (rtx insn, bool replace_p, bool first_p)
{
int icode = recog_memoized (insn);
rtx old_set = single_set (insn);
if (! replace_p)
{
offset += (ep->offset - ep->previous_offset);
+ if (first_p && ep->to_rtx == stack_pointer_rtx)
+ offset -= lra_get_insn_recog_data (insn)->sp_offset;
offset = trunc_int_for_mode (offset, GET_MODE (plus_cst_src));
}
/* Companion to the above plus substitution, we can allow
invariants as the source of a plain move. */
substed_operand[i]
- = lra_eliminate_regs_1 (*id->operand_loc[i], VOIDmode,
- replace_p, ! replace_p, false);
+ = lra_eliminate_regs_1 (insn, *id->operand_loc[i], VOIDmode,
+ replace_p, ! replace_p && ! first_p,
+ first_p);
if (substed_operand[i] != orig_operand[i])
validate_p = true;
}
}
/* Update all offsets and possibility for elimination on eliminable
- registers. Spill pseudos assigned to registers which became
+ registers. Spill pseudos assigned to registers which are
uneliminable, update LRA_NO_ALLOC_REGS and ELIMINABLE_REG_SET. Add
insns to INSNS_WITH_CHANGED_OFFSETS containing eliminable hard
registers whose offsets should be changed. Return true if any
/* Clear self elimination offsets. */
for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++)
self_elim_offsets[ep->from] = 0;
- CLEAR_HARD_REG_SET (temp_hard_reg_set);
for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++)
{
/* If it is a currently used elimination: update the previous
fprintf (lra_dump_file,
" Elimination %d to %d is not possible anymore\n",
ep->from, ep->to);
+ /* If after processing RTL we decides that SP can be used as
+ a result of elimination, it can not be changed. */
+ gcc_assert (ep->to_rtx != stack_pointer_rtx);
/* Mark that is not eliminable anymore. */
elimination_map[ep->from] = NULL;
for (ep1 = ep + 1; ep1 < ®_eliminate[NUM_ELIMINABLE_REGS]; ep1++)
if (lra_dump_file != NULL)
fprintf (lra_dump_file, " Using elimination %d to %d now\n",
ep1->from, ep1->to);
- /* Prevent the hard register into which we eliminate now
- from the usage for pseudos. */
- SET_HARD_REG_BIT (temp_hard_reg_set, ep1->to);
lra_assert (ep1->previous_offset == 0);
ep1->previous_offset = ep->offset;
}
fprintf (lra_dump_file, " %d is not eliminable at all\n",
ep->from);
self_elim_offsets[ep->from] = -ep->offset;
- SET_HARD_REG_BIT (temp_hard_reg_set, ep->from);
if (ep->offset != 0)
bitmap_ior_into (insns_with_changed_offsets,
&lra_reg_info[ep->from].insn_bitmap);
INITIAL_FRAME_POINTER_OFFSET (ep->offset);
#endif
}
- IOR_HARD_REG_SET (lra_no_alloc_regs, temp_hard_reg_set);
- AND_COMPL_HARD_REG_SET (eliminable_regset, temp_hard_reg_set);
- spill_pseudos (temp_hard_reg_set);
setup_elimination_map ();
result = false;
+ CLEAR_HARD_REG_SET (temp_hard_reg_set);
for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++)
- if (elimination_map[ep->from] == ep && ep->previous_offset != ep->offset)
+ if (elimination_map[ep->from] == NULL)
+ SET_HARD_REG_BIT (temp_hard_reg_set, ep->from);
+ else if (elimination_map[ep->from] == ep)
{
- bitmap_ior_into (insns_with_changed_offsets,
- &lra_reg_info[ep->from].insn_bitmap);
-
- /* Update offset when the eliminate offset have been
- changed. */
- lra_update_reg_val_offset (lra_reg_info[ep->from].val,
- ep->offset - ep->previous_offset);
- result = true;
+ /* Prevent the hard register into which we eliminate from
+ the usage for pseudos. */
+ if (ep->from != ep->to)
+ SET_HARD_REG_BIT (temp_hard_reg_set, ep->to);
+ if (ep->previous_offset != ep->offset)
+ {
+ bitmap_ior_into (insns_with_changed_offsets,
+ &lra_reg_info[ep->from].insn_bitmap);
+
+ /* Update offset when the eliminate offset have been
+ changed. */
+ lra_update_reg_val_offset (lra_reg_info[ep->from].val,
+ ep->offset - ep->previous_offset);
+ result = true;
+ }
}
+ IOR_HARD_REG_SET (lra_no_alloc_regs, temp_hard_reg_set);
+ AND_COMPL_HARD_REG_SET (eliminable_regset, temp_hard_reg_set);
+ spill_pseudos (temp_hard_reg_set);
return result;
}
setup_can_eliminate (®_eliminate[0], ! frame_pointer_needed);
#endif
- /* Count the number of eliminable registers and build the FROM and TO
- REG rtx's. Note that code in gen_rtx_REG will cause, e.g.,
- gen_rtx_REG (Pmode, STACK_POINTER_REGNUM) to equal stack_pointer_rtx.
- We depend on this. */
+ /* Build the FROM and TO REG rtx's. Note that code in gen_rtx_REG
+ will cause, e.g., gen_rtx_REG (Pmode, STACK_POINTER_REGNUM) to
+ equal stack_pointer_rtx. We depend on this. Threfore we switch
+ off that we are in LRA temporarily. */
+ lra_in_progress = 0;
for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++)
{
ep->from_rtx = gen_rtx_REG (Pmode, ep->from);
ep->to_rtx = gen_rtx_REG (Pmode, ep->to);
eliminable_reg_rtx[ep->from] = ep->from_rtx;
}
+ lra_in_progress = 1;
}
-/* Entry function for initialization of elimination once per
- function. */
-void
-lra_init_elimination (void)
+/* Function for initialization of elimination once per function. It
+ sets up sp offset for each insn. */
+static void
+init_elimination (void)
{
+ bool stop_to_sp_elimination_p;
basic_block bb;
rtx insn;
+ struct elim_table *ep;
init_elim_table ();
FOR_EACH_BB (bb)
- FOR_BB_INSNS (bb, insn)
- if (NONDEBUG_INSN_P (insn))
- mark_not_eliminable (PATTERN (insn));
+ {
+ curr_sp_change = 0;
+ stop_to_sp_elimination_p = false;
+ FOR_BB_INSNS (bb, insn)
+ if (INSN_P (insn))
+ {
+ lra_get_insn_recog_data (insn)->sp_offset = curr_sp_change;
+ if (NONDEBUG_INSN_P (insn))
+ {
+ mark_not_eliminable (PATTERN (insn), VOIDmode);
+ if (curr_sp_change != 0
+ && find_reg_note (insn, REG_LABEL_OPERAND, NULL_RTX))
+ stop_to_sp_elimination_p = true;
+ }
+ }
+ if (! frame_pointer_needed
+ && (curr_sp_change != 0 || stop_to_sp_elimination_p)
+ && bb->succs && bb->succs->length () != 0)
+ for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++)
+ if (ep->to == STACK_POINTER_REGNUM)
+ setup_can_eliminate (ep, false);
+ }
setup_elimination_map ();
}
*loc = ep->to_rtx;
}
-/* Do (final if FINAL_P) elimination in INSN. Add the insn for
- subsequent processing in the constraint pass, update the insn info. */
+/* Do (final if FINAL_P or first if FIRST_P) elimination in INSN. Add
+ the insn for subsequent processing in the constraint pass, update
+ the insn info. */
static void
-process_insn_for_elimination (rtx insn, bool final_p)
+process_insn_for_elimination (rtx insn, bool final_p, bool first_p)
{
- eliminate_regs_in_insn (insn, final_p);
+ eliminate_regs_in_insn (insn, final_p, first_p);
if (! final_p)
{
/* Check that insn changed its code. This is a case when a move
}
/* Entry function to do final elimination if FINAL_P or to update
- elimination register offsets. */
+ elimination register offsets (FIRST_P if we are doing it the first
+ time). */
void
-lra_eliminate (bool final_p)
+lra_eliminate (bool final_p, bool first_p)
{
- int i;
unsigned int uid;
- rtx mem_loc, invariant;
bitmap_head insns_with_changed_offsets;
bitmap_iterator bi;
struct elim_table *ep;
- int regs_num = max_reg_num ();
+
+ gcc_assert (! final_p || ! first_p);
timevar_push (TV_LRA_ELIMINATE);
+ if (first_p)
+ init_elimination ();
+
bitmap_initialize (&insns_with_changed_offsets, ®_obstack);
if (final_p)
{
fprintf (lra_dump_file, "New elimination table:\n");
print_elim_table (lra_dump_file);
}
- for (i = FIRST_PSEUDO_REGISTER; i < regs_num; i++)
- if (lra_reg_info[i].nrefs != 0)
- {
- mem_loc = ira_reg_equiv[i].memory;
- if (mem_loc != NULL_RTX)
- mem_loc = lra_eliminate_regs_1 (mem_loc, VOIDmode,
- final_p, ! final_p, false);
- ira_reg_equiv[i].memory = mem_loc;
- invariant = ira_reg_equiv[i].invariant;
- if (invariant != NULL_RTX)
- invariant = lra_eliminate_regs_1 (invariant, VOIDmode,
- final_p, ! final_p, false);
- ira_reg_equiv[i].invariant = invariant;
- if (lra_dump_file != NULL
- && (mem_loc != NULL_RTX || invariant != NULL))
- fprintf (lra_dump_file,
- "Updating elimination of equiv for reg %d\n", i);
- }
EXECUTE_IF_SET_IN_BITMAP (&insns_with_changed_offsets, 0, uid, bi)
/* A dead insn can be deleted in process_insn_for_elimination. */
if (lra_insn_recog_data[uid] != NULL)
- process_insn_for_elimination (lra_insn_recog_data[uid]->insn, final_p);
+ process_insn_for_elimination (lra_insn_recog_data[uid]->insn,
+ final_p, first_p);
bitmap_clear (&insns_with_changed_offsets);
lra_eliminate_done:
{
/* The insn code. */
int icode;
+ /* The alternative should be used for the insn, -1 if invalid, or we
+ should try to use any alternative, or the insn is a debug
+ insn. */
+ int used_insn_alternative;
+ /* SP offset before the insn relative to one at the func start. */
+ HOST_WIDE_INT sp_offset;
/* The insn itself. */
rtx insn;
/* Common data for insns with the same ICODE. Asm insns (their
int *arg_hard_regs;
/* Alternative enabled for the insn. NULL for debug insns. */
bool *alternative_enabled_p;
- /* The alternative should be used for the insn, -1 if invalid, or we
- should try to use any alternative, or the insn is a debug
- insn. */
- int used_insn_alternative;
/* The following member value is always NULL for a debug insn. */
struct lra_insn_reg *regs;
};
extern void lra_debug_elim_table (void);
extern int lra_get_elimination_hard_regno (int);
-extern rtx lra_eliminate_regs_1 (rtx, enum machine_mode, bool, bool, bool);
-extern void lra_eliminate (bool);
+extern rtx lra_eliminate_regs_1 (rtx, rtx, enum machine_mode, bool, bool, bool);
+extern void lra_eliminate (bool, bool);
extern void lra_eliminate_reg_if_possible (rtx *);
x = assign_stack_local (mode, total_size,
min_align > inherent_align
|| total_size > inherent_size ? -1 : 0);
- x = lra_eliminate_regs_1 (x, GET_MODE (x), false, false, true);
stack_slot = x;
/* Cancel the big-endian correction done in assign_stack_local.
Get the address of the beginning of the slot. This is so we
into scratches back. */
&& ! lra_former_scratch_p (i))
{
- hard_reg = spill_hard_reg[i];
- *loc = copy_rtx (hard_reg != NULL_RTX ? hard_reg : pseudo_slots[i].mem);
+ if ((hard_reg = spill_hard_reg[i]) != NULL_RTX)
+ *loc = copy_rtx (hard_reg);
+ else
+ {
+ rtx x = lra_eliminate_regs_1 (insn, pseudo_slots[i].mem,
+ GET_MODE (pseudo_slots[i].mem),
+ false, false, true);
+ *loc = x != pseudo_slots[i].mem ? x : copy_rtx (x);
+ }
return;
}
FOR_BB_INSNS (bb, insn)
if (bitmap_bit_p (&changed_insns, INSN_UID (insn)))
{
+ rtx *link_loc, link;
remove_pseudos (&PATTERN (insn), insn);
if (CALL_P (insn))
remove_pseudos (&CALL_INSN_FUNCTION_USAGE (insn), insn);
+ for (link_loc = ®_NOTES (insn);
+ (link = *link_loc) != NULL_RTX;
+ link_loc = &XEXP (link, 1))
+ {
+ switch (REG_NOTE_KIND (link))
+ {
+ case REG_FRAME_RELATED_EXPR:
+ case REG_CFA_DEF_CFA:
+ case REG_CFA_ADJUST_CFA:
+ case REG_CFA_OFFSET:
+ case REG_CFA_REGISTER:
+ case REG_CFA_EXPRESSION:
+ case REG_CFA_RESTORE:
+ case REG_CFA_SET_VDRAP:
+ remove_pseudos (&XEXP (link, 0), insn);
+ break;
+ default:
+ break;
+ }
+ }
if (lra_dump_file != NULL)
fprintf (lra_dump_file,
"Changing spilled pseudos to memory in insn #%u\n",
lra_reg_info[regno].val = get_new_reg_value ();
}
-/* Invalidate INSN related info used by LRA. */
+/* Invalidate INSN related info used by LRA. The info should never be
+ used after that. */
void
lra_invalidate_insn_data (rtx insn)
{
int n;
unsigned int uid = INSN_UID (insn);
struct lra_static_insn_data *insn_static_data;
+ HOST_WIDE_INT sp_offset = 0;
check_and_expand_insn_recog_data (uid);
if ((data = lra_insn_recog_data[uid]) != NULL
&& data->icode != INSN_CODE (insn))
{
+ sp_offset = data->sp_offset;
invalidate_insn_data_regno_info (data, insn, get_insn_freq (insn));
invalidate_insn_recog_data (uid);
data = NULL;
}
if (data == NULL)
- return lra_get_insn_recog_data (insn);
+ {
+ data = lra_get_insn_recog_data (insn);
+ /* Initiate or restore SP offset. */
+ data->sp_offset = sp_offset;
+ return data;
+ }
insn_static_data = data->insn_static_data;
data->used_insn_alternative = -1;
if (DEBUG_INSN_P (insn))
lra_push_insn (insn);
}
+/* Set up sp offset for insn in range [FROM, LAST]. The offset is
+ taken from the next BB insn after LAST or zero if there in such
+ insn. */
+static void
+setup_sp_offset (rtx from, rtx last)
+{
+ rtx before = next_nonnote_insn_bb (last);
+ HOST_WIDE_INT offset = (before == NULL_RTX || ! INSN_P (before)
+ ? 0 : lra_get_insn_recog_data (before)->sp_offset);
+
+ for (rtx insn = from; insn != NEXT_INSN (last); insn = NEXT_INSN (insn))
+ lra_get_insn_recog_data (insn)->sp_offset = offset;
+}
+
/* Emit insns BEFORE before INSN and insns AFTER after INSN. Put the
insns onto the stack. Print about emitting the insns with
TITLE. */
{
rtx last;
- if (lra_dump_file != NULL && (before != NULL_RTX || after != NULL_RTX))
+ if (before == NULL_RTX && after == NULL_RTX)
+ return;
+ if (lra_dump_file != NULL)
{
dump_insn_slim (lra_dump_file, insn);
if (before != NULL_RTX)
{
emit_insn_before (before, insn);
push_insns (PREV_INSN (insn), PREV_INSN (before));
+ setup_sp_offset (before, PREV_INSN (insn));
}
if (after != NULL_RTX)
{
;
emit_insn_after (after, insn);
push_insns (last, insn);
+ setup_sp_offset (after, last);
}
}
correctly decomposed. LRA can generate reloads for
decomposable addresses. The decomposition code checks the
correctness of the addresses. So we don't need to check
- the addresses here. */
- if (insn_invalid_p (insn, false))
+ the addresses here. Don't call insn_invalid_p here, it can
+ change the code at this stage. */
+ if (recog_memoized (insn) < 0 && asm_noperands (PATTERN (insn)) < 0)
fatal_insn_not_found (insn);
}
}
init_insn_recog_data ();
- /* We can not set up reload_in_progress because it prevents new
- pseudo creation. */
- lra_in_progress = 1;
-
#ifdef ENABLE_CHECKING
+ /* Some quick check on RTL generated by previous passes. */
check_rtl (false);
#endif
+ lra_in_progress = 1;
+
lra_live_range_iter = lra_coalesce_iter = 0;
lra_constraint_iter = lra_constraint_iter_after_spill = 0;
lra_inheritance_iter = lra_undo_inheritance_iter = 0;
For example, rs6000 can make
RS6000_PIC_OFFSET_TABLE_REGNUM uneliminable if we started
to use a constant pool. */
- lra_eliminate (false);
+ lra_eliminate (false, false);
/* Do inheritance only for regular algorithms. */
if (! lra_simple_p)
lra_inheritance ();
lra_spill ();
/* Assignment of stack slots changes elimination offsets for
some eliminations. So update the offsets here. */
- lra_eliminate (false);
+ lra_eliminate (false, false);
lra_constraint_new_regno_start = max_reg_num ();
lra_constraint_new_insn_uid_start = get_max_uid ();
lra_constraint_iter_after_spill = 0;
}
restore_scratches ();
- lra_eliminate (true);
+ lra_eliminate (true, false);
lra_final_code_change ();
lra_in_progress = 0;
if (live_p)
extern rtx lra_create_new_reg (enum machine_mode, rtx, enum reg_class,
const char *);
-extern void lra_init_elimination (void);
extern rtx lra_eliminate_regs (rtx, enum machine_mode, rtx);
extern void lra (FILE *);
extern void lra_init_once (void);
#include "tm.h"
#include "tree.h"
#include "stringpool.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "expr.h"
#include "flags.h"
#include "input.h"
#include "hashtab.h"
#include "langhooks.h"
-#include "basic-block.h"
#include "bitmap.h"
#include "function.h"
-#include "ggc.h"
#include "diagnostic-core.h"
#include "except.h"
-#include "vec.h"
#include "timevar.h"
-#include "pointer-set.h"
#include "lto-streamer.h"
#include "data-streamer.h"
#include "tree-streamer.h"
&& boundary_p && !DECL_EXTERNAL (node->decl), 1);
/* in_other_partition. */
}
- bp_pack_value (&bp, node->need_bounds_init, 1);
streamer_write_bitpack (&bp);
if (node->same_comdat_group && !boundary_p)
{
node->analyzed = bp_unpack_value (&bp, 1);
node->used_from_other_partition = bp_unpack_value (&bp, 1);
node->in_other_partition = bp_unpack_value (&bp, 1);
- node->need_bounds_init = bp_unpack_value (&bp, 1);
if (node->in_other_partition)
{
DECL_EXTERNAL (node->decl) = 1;
#include <zlib.h>
#include "coretypes.h"
#include "tree.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "diagnostic-core.h"
#include "langhooks.h"
#include "system.h"
#include "coretypes.h"
#include "tree.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "hashtab.h"
-#include "ggc.h"
-#include "vec.h"
#include "bitmap.h"
#include "flags.h"
#include "opts.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "expr.h"
#include "flags.h"
#include "params.h"
#include "input.h"
#include "hashtab.h"
-#include "basic-block.h"
#include "function.h"
-#include "ggc.h"
#include "diagnostic-core.h"
#include "except.h"
-#include "vec.h"
#include "timevar.h"
#include "lto-streamer.h"
#include "lto-compress.h"
-#include "ggc.h"
/* Section names. These must correspond to the values of
enum lto_section_type. */
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "expr.h"
#include "params.h"
#include "input.h"
#include "hashtab.h"
-#include "basic-block.h"
#include "function.h"
-#include "ggc.h"
#include "except.h"
-#include "vec.h"
-#include "pointer-set.h"
#include "langhooks.h"
#include "data-streamer.h"
#include "lto-streamer.h"
#include "input.h"
#include "hashtab.h"
#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "tree-ssa.h"
#include "tree-pass.h"
#include "function.h"
-#include "ggc.h"
#include "diagnostic.h"
#include "except.h"
#include "debug.h"
-#include "vec.h"
#include "ipa-utils.h"
#include "data-streamer.h"
#include "gimple-streamer.h"
/* Read the CFG for function FN from input block IB. */
static void
-input_cfg (struct lto_input_block *ib, struct function *fn,
+input_cfg (struct lto_input_block *ib, struct data_in *data_in,
+ struct function *fn,
int count_materialization_scale)
{
unsigned int bb_count;
loop->nb_iterations_estimate = widest_int::from_array (a, len);
}
+ /* Read OMP SIMD related info. */
+ loop->safelen = streamer_read_hwi (ib);
+ loop->force_vect = streamer_read_hwi (ib);
+ loop->simduid = stream_read_tree (ib, data_in);
+
place_new_loop (fn, loop);
/* flow_loops_find doesn't like loops not in the tree, hook them
fn->has_nonlocal_label = bp_unpack_value (&bp, 1);
fn->calls_alloca = bp_unpack_value (&bp, 1);
fn->calls_setjmp = bp_unpack_value (&bp, 1);
+ fn->has_force_vect_loops = bp_unpack_value (&bp, 1);
+ fn->has_simduid_loops = bp_unpack_value (&bp, 1);
fn->va_list_fpr_size = bp_unpack_value (&bp, 8);
fn->va_list_gpr_size = bp_unpack_value (&bp, 8);
if (!node)
node = cgraph_create_node (fn_decl);
input_struct_function_base (fn, data_in, ib);
- input_cfg (ib_cfg, fn, node->count_materialization_scale);
+ input_cfg (ib_cfg, data_in, fn, node->count_materialization_scale);
/* Read all the SSA names. */
input_ssa_names (ib, data_in, fn);
#include "input.h"
#include "hashtab.h"
#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "tree-ssanames.h"
#include "tree-pass.h"
#include "function.h"
-#include "ggc.h"
#include "diagnostic-core.h"
#include "except.h"
-#include "vec.h"
#include "lto-symtab.h"
#include "lto-streamer.h"
#include "data-streamer.h"
definition. */
if (TREE_CODE (t) == PARM_DECL || TREE_CODE (t) == RESULT_DECL)
return variably_modified_type_p (TREE_TYPE (DECL_CONTEXT (t)), NULL_TREE);
- else if (TREE_CODE (t) == VAR_DECL && decl_function_context (t)
- && !TREE_STATIC (t))
+ else if (((TREE_CODE (t) == VAR_DECL && !TREE_STATIC (t))
+ || TREE_CODE (t) == TYPE_DECL
+ || TREE_CODE (t) == CONST_DECL)
+ && decl_function_context (t))
return false;
else if (TREE_CODE (t) == DEBUG_EXPR_DECL)
return false;
&& code != BIND_EXPR
&& code != WITH_CLEANUP_EXPR
&& code != STATEMENT_LIST
- && code != OMP_CLAUSE
&& (code == CASE_LABEL_EXPR
|| code == DECL_EXPR
|| TREE_CODE_CLASS (code) != tcc_statement);
}
}
+ if (code == OMP_CLAUSE)
+ {
+ int i;
+ for (i = 0; i < omp_clause_num_ops[OMP_CLAUSE_CODE (expr)]; i++)
+ DFS_follow_tree_edge (OMP_CLAUSE_OPERAND (expr, i));
+ DFS_follow_tree_edge (OMP_CLAUSE_CHAIN (expr));
+ }
+
#undef DFS_follow_tree_edge
}
}
}
+ if (code == OMP_CLAUSE)
+ {
+ int i;
+
+ v = iterative_hash_host_wide_int (OMP_CLAUSE_CODE (t), v);
+ switch (OMP_CLAUSE_CODE (t))
+ {
+ case OMP_CLAUSE_DEFAULT:
+ v = iterative_hash_host_wide_int (OMP_CLAUSE_DEFAULT_KIND (t), v);
+ break;
+ case OMP_CLAUSE_SCHEDULE:
+ v = iterative_hash_host_wide_int (OMP_CLAUSE_SCHEDULE_KIND (t), v);
+ break;
+ case OMP_CLAUSE_DEPEND:
+ v = iterative_hash_host_wide_int (OMP_CLAUSE_DEPEND_KIND (t), v);
+ break;
+ case OMP_CLAUSE_MAP:
+ v = iterative_hash_host_wide_int (OMP_CLAUSE_MAP_KIND (t), v);
+ break;
+ case OMP_CLAUSE_PROC_BIND:
+ v = iterative_hash_host_wide_int (OMP_CLAUSE_PROC_BIND_KIND (t), v);
+ break;
+ case OMP_CLAUSE_REDUCTION:
+ v = iterative_hash_host_wide_int (OMP_CLAUSE_REDUCTION_CODE (t), v);
+ break;
+ default:
+ break;
+ }
+ for (i = 0; i < omp_clause_num_ops[OMP_CLAUSE_CODE (t)]; i++)
+ visit (OMP_CLAUSE_OPERAND (t, i));
+ visit (OMP_CLAUSE_CHAIN (t));
+ }
+
return v;
#undef visit
for (i = 0; i < len; i++)
streamer_write_hwi (ob, loop->nb_iterations_estimate.elt (i));
}
+
+ /* Write OMP SIMD related info. */
+ streamer_write_hwi (ob, loop->safelen);
+ streamer_write_hwi (ob, loop->force_vect);
+ stream_write_tree (ob, loop->simduid, true);
}
ob->main_stream = tmp_stream;
bp_pack_value (&bp, fn->has_nonlocal_label, 1);
bp_pack_value (&bp, fn->calls_alloca, 1);
bp_pack_value (&bp, fn->calls_setjmp, 1);
+ bp_pack_value (&bp, fn->has_force_vect_loops, 1);
+ bp_pack_value (&bp, fn->has_simduid_loops, 1);
bp_pack_value (&bp, fn->va_list_fpr_size, 8);
bp_pack_value (&bp, fn->va_list_gpr_size, 8);
#include "toplev.h"
#include "flags.h"
#include "tree.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "bitmap.h"
#include "diagnostic-core.h"
-#include "vec.h"
#include "tree-streamer.h"
#include "lto-streamer.h"
#include "streamer-hooks.h"
+2013-11-29 Jakub Jelinek <jakub@redhat.com>
+ Richard Biener <rguenther@suse.de>
+
+ PR lto/59326
+ * lto.c (compare_tree_sccs_1): Handle OMP_CLAUSE.
+
+2013-11-29 Jakub Jelinek <jakub@redhat.com>
+
+ PR lto/59326
+ * lto.c (mentions_vars_p_omp_clause): New function.
+ (mentions_vars_p): Call it for OMP_CLAUSE. Remove break;
+ after return stmts.
+
+2013-11-22 Andrew MacLeod <amacleod@redhat.com>
+
+ * lto.c: Add required include files from gimple.h.
+ * lto-lang.c: Likewise
+ * lto-object.c: Likewise
+ * lto-partition.c: Likewise
+ * lto-symtab.c: Likewise
+
2013-11-18 Trevor Saunders <tsaunders@mozilla.com>
* lto-partition.c lto-symtab.c lto.c Adjust.
#include "lto-tree.h"
#include "lto.h"
#include "tree-inline.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "diagnostic-core.h"
#include "toplev.h"
return TS_LTO_GENERIC;
}
-#include "ggc.h"
#include "gtype-lto.h"
#include "gt-lto-lto-lang.h"
#include "system.h"
#include "coretypes.h"
#include "tree.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "diagnostic-core.h"
#include "lto.h"
#include "toplev.h"
#include "tree.h"
#include "gcc-symtab.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "tm.h"
#include "cgraph.h"
#include "coretypes.h"
#include "diagnostic-core.h"
#include "tree.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
-#include "ggc.h"
#include "hashtab.h"
#include "plugin-api.h"
#include "lto-streamer.h"
#include "diagnostic-core.h"
#include "tm.h"
#include "cgraph.h"
-#include "ggc.h"
#include "tree-ssa-operands.h"
#include "tree-pass.h"
#include "langhooks.h"
-#include "vec.h"
#include "bitmap.h"
-#include "pointer-set.h"
#include "ipa-prop.h"
#include "common.h"
#include "debug.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "lto.h"
#include "lto-tree.h"
return false;
}
+/* Check presence of pointers to decls in fields of an OMP_CLAUSE T. */
+
+static bool
+mentions_vars_p_omp_clause (tree t)
+{
+ int i;
+ if (mentions_vars_p_common (t))
+ return true;
+ for (i = omp_clause_num_ops[OMP_CLAUSE_CODE (t)] - 1; i >= 0; --i)
+ CHECK_VAR (OMP_CLAUSE_OPERAND (t, i));
+ return false;
+}
+
/* Check presence of pointers to decls that needs later fixup in T. */
static bool
case FIELD_DECL:
return mentions_vars_p_field_decl (t);
- break;
case LABEL_DECL:
case CONST_DECL:
case IMPORTED_DECL:
case NAMESPACE_DECL:
return mentions_vars_p_decl_common (t);
- break;
case VAR_DECL:
return mentions_vars_p_decl_with_vis (t);
- break;
case TYPE_DECL:
return mentions_vars_p_decl_non_common (t);
- break;
case FUNCTION_DECL:
return mentions_vars_p_function (t);
- break;
case TREE_BINFO:
return mentions_vars_p_binfo (t);
- break;
case PLACEHOLDER_EXPR:
return mentions_vars_p_common (t);
- break;
case BLOCK:
case TRANSLATION_UNIT_DECL:
case CONSTRUCTOR:
return mentions_vars_p_constructor (t);
- break;
+
+ case OMP_CLAUSE:
+ return mentions_vars_p_omp_clause (t);
default:
if (TYPE_P (t))
TREE_STRING_LENGTH (t1)) != 0)
return false;
+ if (code == OMP_CLAUSE)
+ {
+ compare_values (OMP_CLAUSE_CODE);
+ switch (OMP_CLAUSE_CODE (t1))
+ {
+ case OMP_CLAUSE_DEFAULT:
+ compare_values (OMP_CLAUSE_DEFAULT_KIND);
+ break;
+ case OMP_CLAUSE_SCHEDULE:
+ compare_values (OMP_CLAUSE_SCHEDULE_KIND);
+ break;
+ case OMP_CLAUSE_DEPEND:
+ compare_values (OMP_CLAUSE_DEPEND_KIND);
+ break;
+ case OMP_CLAUSE_MAP:
+ compare_values (OMP_CLAUSE_MAP_KIND);
+ break;
+ case OMP_CLAUSE_PROC_BIND:
+ compare_values (OMP_CLAUSE_PROC_BIND_KIND);
+ break;
+ case OMP_CLAUSE_REDUCTION:
+ compare_values (OMP_CLAUSE_REDUCTION_CODE);
+ compare_values (OMP_CLAUSE_REDUCTION_GIMPLE_INIT);
+ compare_values (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE);
+ break;
+ default:
+ break;
+ }
+ }
+
#undef compare_values
}
}
+ if (code == OMP_CLAUSE)
+ {
+ int i;
+
+ for (i = 0; i < omp_clause_num_ops[OMP_CLAUSE_CODE (t1)]; i++)
+ compare_tree_edges (OMP_CLAUSE_OPERAND (t1, i),
+ OMP_CLAUSE_OPERAND (t2, i));
+ compare_tree_edges (OMP_CLAUSE_CHAIN (t1), OMP_CLAUSE_CHAIN (t2));
+ }
+
#undef compare_tree_edges
return true;
|| CLASS == MODE_ACCUM \
|| CLASS == MODE_UACCUM)
-#define POINTER_BOUNDS_MODE_P(MODE) \
- (GET_MODE_CLASS (MODE) == MODE_POINTER_BOUNDS)
-
/* Get the size in bytes and bits of an object of mode MODE. */
extern CONST_MODE_SIZE unsigned char mode_size[NUM_MACHINE_MODES];
DEF_MODE_CLASS (MODE_CC), /* condition code in a register */ \
DEF_MODE_CLASS (MODE_INT), /* integer */ \
DEF_MODE_CLASS (MODE_PARTIAL_INT), /* integer with padding bits */ \
- DEF_MODE_CLASS (MODE_POINTER_BOUNDS), /* bounds */ \
DEF_MODE_CLASS (MODE_FRACT), /* signed fractional number */ \
DEF_MODE_CLASS (MODE_UFRACT), /* unsigned fractional number */ \
DEF_MODE_CLASS (MODE_ACCUM), /* signed accumulator */ \
+2013-11-22 Andrew MacLeod <amacleod@redhat.com>
+
+ * objc/objc-act.c: Add required include files from gimple.h.
+
2013-11-18 Richard Sandiford <rdsandiford@googlemail.com>
* objc-encoding.c: Replace tree_low_cst (..., 1) with tree_to_uhwi
#include "input.h"
#include "function.h"
#include "toplev.h"
-#include "ggc.h"
#include "debug.h"
#include "c-family/c-target.h"
#include "diagnostic-core.h"
#include "tree-pretty-print.h"
/* For enum gimplify_status */
-#include "gimple.h"
+#include "gimple-expr.h"
#include "gimplify.h"
/* For encode_method_prototype(). */
#include "stringpool.h"
#include "stor-layout.h"
#include "rtl.h"
+#include "pointer-set.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-fold.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimplify.h"
#include "gimple-iterator.h"
#include "function.h"
#include "expr.h"
#include "tree-pass.h"
-#include "ggc.h"
#include "except.h"
#include "splay-tree.h"
#include "optabs.h"
#include "omp-low.h"
#include "gimple-low.h"
#include "tree-cfgcleanup.h"
+#include "pretty-print.h"
+#include "ipa-prop.h"
#include "tree-nested.h"
+#include "tree-eh.h"
/* Lowering of OpenMP parallel and workshare constructs proceeds in two
}
else if (TREE_CONSTANT (x))
{
- const char *name = NULL;
- if (DECL_NAME (var))
- name = IDENTIFIER_POINTER (DECL_NAME (new_var));
-
- x = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (new_var)),
- name);
- gimple_add_tmp_var (x);
- TREE_ADDRESSABLE (x) = 1;
- x = build_fold_addr_expr_loc (clause_loc, x);
+ /* For reduction with placeholder in SIMD loop,
+ defer adding the initialization of the reference,
+ because if we decide to use SIMD array for it,
+ the initilization could cause expansion ICE. */
+ if (c_kind == OMP_CLAUSE_REDUCTION
+ && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
+ && is_simd)
+ x = NULL_TREE;
+ else
+ {
+ const char *name = NULL;
+ if (DECL_NAME (var))
+ name = IDENTIFIER_POINTER (DECL_NAME (new_var));
+
+ x = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (new_var)),
+ name);
+ gimple_add_tmp_var (x);
+ TREE_ADDRESSABLE (x) = 1;
+ x = build_fold_addr_expr_loc (clause_loc, x);
+ }
}
else
{
x = build_call_expr_loc (clause_loc, atmp, 1, x);
}
- x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x);
- gimplify_assign (new_var, x, ilist);
+ if (x)
+ {
+ x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x);
+ gimplify_assign (new_var, x, ilist);
+ }
new_var = build_simple_mem_ref_loc (clause_loc, new_var);
}
}
break;
}
+ /* If this is a reference to constant size reduction var
+ with placeholder, we haven't emitted the initializer
+ for it because it is undesirable if SIMD arrays are used.
+ But if they aren't used, we need to emit the deferred
+ initialization now. */
+ else if (is_reference (var) && is_simd)
+ {
+ tree z
+ = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (new_vard)));
+ if (TREE_CONSTANT (z))
+ {
+ const char *name = NULL;
+ if (DECL_NAME (var))
+ name = IDENTIFIER_POINTER (DECL_NAME (new_vard));
+
+ z = create_tmp_var_raw
+ (TREE_TYPE (TREE_TYPE (new_vard)), name);
+ gimple_add_tmp_var (z);
+ TREE_ADDRESSABLE (z) = 1;
+ z = build_fold_addr_expr_loc (clause_loc, z);
+ gimplify_assign (new_vard, z, ilist);
+ }
+ }
x = lang_hooks.decls.omp_clause_default_ctor
(c, new_var, unshare_expr (x));
if (x)
{
struct loop *loop = alloc_loop ();
loop->header = body_bb;
- loop->latch = cont_bb;
+ if (collapse_bb == NULL)
+ loop->latch = cont_bb;
add_loop (loop, trip_loop);
}
}
{
struct loop *loop = alloc_loop ();
loop->header = l1_bb;
- loop->latch = e->dest;
+ loop->latch = cont_bb;
add_loop (loop, l1_bb->loop_father);
if (safelen == NULL_TREE)
loop->safelen = INT_MAX;
{
return new pass_diagnose_omp_blocks (ctxt);
}
+\f
+/* SIMD clone supporting code. */
+
+/* Allocate a fresh `simd_clone' and return it. NARGS is the number
+ of arguments to reserve space for. */
+
+static struct cgraph_simd_clone *
+simd_clone_struct_alloc (int nargs)
+{
+ struct cgraph_simd_clone *clone_info;
+ size_t len = (sizeof (struct cgraph_simd_clone)
+ + nargs * sizeof (struct cgraph_simd_clone_arg));
+ clone_info = (struct cgraph_simd_clone *)
+ ggc_internal_cleared_alloc_stat (len PASS_MEM_STAT);
+ return clone_info;
+}
+
+/* Make a copy of the `struct cgraph_simd_clone' in FROM to TO. */
+
+static inline void
+simd_clone_struct_copy (struct cgraph_simd_clone *to,
+ struct cgraph_simd_clone *from)
+{
+ memcpy (to, from, (sizeof (struct cgraph_simd_clone)
+ + from->nargs * sizeof (struct cgraph_simd_clone_arg)));
+}
+
+/* Return vector of parameter types of function FNDECL. This uses
+ TYPE_ARG_TYPES if available, otherwise falls back to types of
+ DECL_ARGUMENTS types. */
+
+vec<tree>
+simd_clone_vector_of_formal_parm_types (tree fndecl)
+{
+ if (TYPE_ARG_TYPES (TREE_TYPE (fndecl)))
+ return ipa_get_vector_of_formal_parm_types (TREE_TYPE (fndecl));
+ vec<tree> args = ipa_get_vector_of_formal_parms (fndecl);
+ unsigned int i;
+ tree arg;
+ FOR_EACH_VEC_ELT (args, i, arg)
+ args[i] = TREE_TYPE (args[i]);
+ return args;
+}
+
+/* Given a simd function in NODE, extract the simd specific
+ information from the OMP clauses passed in CLAUSES, and return
+ the struct cgraph_simd_clone * if it should be cloned. *INBRANCH_SPECIFIED
+ is set to TRUE if the `inbranch' or `notinbranch' clause specified,
+ otherwise set to FALSE. */
+
+static struct cgraph_simd_clone *
+simd_clone_clauses_extract (struct cgraph_node *node, tree clauses,
+ bool *inbranch_specified)
+{
+ vec<tree> args = simd_clone_vector_of_formal_parm_types (node->decl);
+ tree t;
+ int n;
+ *inbranch_specified = false;
+
+ n = args.length ();
+ if (n > 0 && args.last () == void_type_node)
+ n--;
+
+ /* To distinguish from an OpenMP simd clone, Cilk Plus functions to
+ be cloned have a distinctive artificial label in addition to "omp
+ declare simd". */
+ bool cilk_clone
+ = (flag_enable_cilkplus
+ && lookup_attribute ("cilk plus elemental",
+ DECL_ATTRIBUTES (node->decl)));
+
+ /* Allocate one more than needed just in case this is an in-branch
+ clone which will require a mask argument. */
+ struct cgraph_simd_clone *clone_info = simd_clone_struct_alloc (n + 1);
+ clone_info->nargs = n;
+ clone_info->cilk_elemental = cilk_clone;
+
+ if (!clauses)
+ {
+ args.release ();
+ return clone_info;
+ }
+ clauses = TREE_VALUE (clauses);
+ if (!clauses || TREE_CODE (clauses) != OMP_CLAUSE)
+ return clone_info;
+
+ for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
+ {
+ switch (OMP_CLAUSE_CODE (t))
+ {
+ case OMP_CLAUSE_INBRANCH:
+ clone_info->inbranch = 1;
+ *inbranch_specified = true;
+ break;
+ case OMP_CLAUSE_NOTINBRANCH:
+ clone_info->inbranch = 0;
+ *inbranch_specified = true;
+ break;
+ case OMP_CLAUSE_SIMDLEN:
+ clone_info->simdlen
+ = TREE_INT_CST_LOW (OMP_CLAUSE_SIMDLEN_EXPR (t));
+ break;
+ case OMP_CLAUSE_LINEAR:
+ {
+ tree decl = OMP_CLAUSE_DECL (t);
+ tree step = OMP_CLAUSE_LINEAR_STEP (t);
+ int argno = TREE_INT_CST_LOW (decl);
+ if (OMP_CLAUSE_LINEAR_VARIABLE_STRIDE (t))
+ {
+ clone_info->args[argno].arg_type
+ = SIMD_CLONE_ARG_TYPE_LINEAR_VARIABLE_STEP;
+ clone_info->args[argno].linear_step = tree_to_shwi (step);
+ gcc_assert (clone_info->args[argno].linear_step >= 0
+ && clone_info->args[argno].linear_step < n);
+ }
+ else
+ {
+ if (POINTER_TYPE_P (args[argno]))
+ step = fold_convert (ssizetype, step);
+ if (!tree_fits_shwi_p (step))
+ {
+ warning_at (OMP_CLAUSE_LOCATION (t), 0,
+ "ignoring large linear step");
+ args.release ();
+ return NULL;
+ }
+ else if (integer_zerop (step))
+ {
+ warning_at (OMP_CLAUSE_LOCATION (t), 0,
+ "ignoring zero linear step");
+ args.release ();
+ return NULL;
+ }
+ else
+ {
+ clone_info->args[argno].arg_type
+ = SIMD_CLONE_ARG_TYPE_LINEAR_CONSTANT_STEP;
+ clone_info->args[argno].linear_step = tree_to_shwi (step);
+ }
+ }
+ break;
+ }
+ case OMP_CLAUSE_UNIFORM:
+ {
+ tree decl = OMP_CLAUSE_DECL (t);
+ int argno = tree_to_uhwi (decl);
+ clone_info->args[argno].arg_type
+ = SIMD_CLONE_ARG_TYPE_UNIFORM;
+ break;
+ }
+ case OMP_CLAUSE_ALIGNED:
+ {
+ tree decl = OMP_CLAUSE_DECL (t);
+ int argno = tree_to_uhwi (decl);
+ clone_info->args[argno].alignment
+ = TREE_INT_CST_LOW (OMP_CLAUSE_ALIGNED_ALIGNMENT (t));
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ args.release ();
+ return clone_info;
+}
+
+/* Given a SIMD clone in NODE, calculate the characteristic data
+ type and return the coresponding type. The characteristic data
+ type is computed as described in the Intel Vector ABI. */
+
+static tree
+simd_clone_compute_base_data_type (struct cgraph_node *node,
+ struct cgraph_simd_clone *clone_info)
+{
+ tree type = integer_type_node;
+ tree fndecl = node->decl;
+
+ /* a) For non-void function, the characteristic data type is the
+ return type. */
+ if (TREE_CODE (TREE_TYPE (TREE_TYPE (fndecl))) != VOID_TYPE)
+ type = TREE_TYPE (TREE_TYPE (fndecl));
+
+ /* b) If the function has any non-uniform, non-linear parameters,
+ then the characteristic data type is the type of the first
+ such parameter. */
+ else
+ {
+ vec<tree> map = simd_clone_vector_of_formal_parm_types (fndecl);
+ for (unsigned int i = 0; i < clone_info->nargs; ++i)
+ if (clone_info->args[i].arg_type == SIMD_CLONE_ARG_TYPE_VECTOR)
+ {
+ type = map[i];
+ break;
+ }
+ map.release ();
+ }
+
+ /* c) If the characteristic data type determined by a) or b) above
+ is struct, union, or class type which is pass-by-value (except
+ for the type that maps to the built-in complex data type), the
+ characteristic data type is int. */
+ if (RECORD_OR_UNION_TYPE_P (type)
+ && !aggregate_value_p (type, NULL)
+ && TREE_CODE (type) != COMPLEX_TYPE)
+ return integer_type_node;
+
+ /* d) If none of the above three classes is applicable, the
+ characteristic data type is int. */
+
+ return type;
+
+ /* e) For Intel Xeon Phi native and offload compilation, if the
+ resulting characteristic data type is 8-bit or 16-bit integer
+ data type, the characteristic data type is int. */
+ /* Well, we don't handle Xeon Phi yet. */
+}
+
+static tree
+simd_clone_mangle (struct cgraph_node *node,
+ struct cgraph_simd_clone *clone_info)
+{
+ char vecsize_mangle = clone_info->vecsize_mangle;
+ char mask = clone_info->inbranch ? 'M' : 'N';
+ unsigned int simdlen = clone_info->simdlen;
+ unsigned int n;
+ pretty_printer pp;
+
+ gcc_assert (vecsize_mangle && simdlen);
+
+ pp_string (&pp, "_ZGV");
+ pp_character (&pp, vecsize_mangle);
+ pp_character (&pp, mask);
+ pp_decimal_int (&pp, simdlen);
+
+ for (n = 0; n < clone_info->nargs; ++n)
+ {
+ struct cgraph_simd_clone_arg arg = clone_info->args[n];
+
+ if (arg.arg_type == SIMD_CLONE_ARG_TYPE_UNIFORM)
+ pp_character (&pp, 'u');
+ else if (arg.arg_type == SIMD_CLONE_ARG_TYPE_LINEAR_CONSTANT_STEP)
+ {
+ gcc_assert (arg.linear_step != 0);
+ pp_character (&pp, 'l');
+ if (arg.linear_step > 1)
+ pp_unsigned_wide_integer (&pp, arg.linear_step);
+ else if (arg.linear_step < 0)
+ {
+ pp_character (&pp, 'n');
+ pp_unsigned_wide_integer (&pp, (-(unsigned HOST_WIDE_INT)
+ arg.linear_step));
+ }
+ }
+ else if (arg.arg_type == SIMD_CLONE_ARG_TYPE_LINEAR_VARIABLE_STEP)
+ {
+ pp_character (&pp, 's');
+ pp_unsigned_wide_integer (&pp, arg.linear_step);
+ }
+ else
+ pp_character (&pp, 'v');
+ if (arg.alignment)
+ {
+ pp_character (&pp, 'a');
+ pp_decimal_int (&pp, arg.alignment);
+ }
+ }
+
+ pp_underscore (&pp);
+ pp_string (&pp,
+ IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (node->decl)));
+ const char *str = pp_formatted_text (&pp);
+
+ /* If there already is a SIMD clone with the same mangled name, don't
+ add another one. This can happen e.g. for
+ #pragma omp declare simd
+ #pragma omp declare simd simdlen(8)
+ int foo (int, int);
+ if the simdlen is assumed to be 8 for the first one, etc. */
+ for (struct cgraph_node *clone = node->simd_clones; clone;
+ clone = clone->simdclone->next_clone)
+ if (strcmp (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (clone->decl)),
+ str) == 0)
+ return NULL_TREE;
+
+ return get_identifier (str);
+}
+
+/* Create a simd clone of OLD_NODE and return it. */
+
+static struct cgraph_node *
+simd_clone_create (struct cgraph_node *old_node)
+{
+ struct cgraph_node *new_node;
+ if (old_node->definition)
+ {
+ if (!cgraph_function_with_gimple_body_p (old_node))
+ return NULL;
+ cgraph_get_body (old_node);
+ new_node = cgraph_function_versioning (old_node, vNULL, NULL, NULL,
+ false, NULL, NULL, "simdclone");
+ }
+ else
+ {
+ tree old_decl = old_node->decl;
+ tree new_decl = copy_node (old_node->decl);
+ DECL_NAME (new_decl) = clone_function_name (old_decl, "simdclone");
+ SET_DECL_ASSEMBLER_NAME (new_decl, DECL_NAME (new_decl));
+ SET_DECL_RTL (new_decl, NULL);
+ DECL_STATIC_CONSTRUCTOR (new_decl) = 0;
+ DECL_STATIC_DESTRUCTOR (new_decl) = 0;
+ new_node
+ = cgraph_copy_node_for_versioning (old_node, new_decl, vNULL, NULL);
+ cgraph_call_function_insertion_hooks (new_node);
+ }
+ if (new_node == NULL)
+ return new_node;
+
+ TREE_PUBLIC (new_node->decl) = TREE_PUBLIC (old_node->decl);
+
+ /* The function cgraph_function_versioning () will force the new
+ symbol local. Undo this, and inherit external visability from
+ the old node. */
+ new_node->local.local = old_node->local.local;
+ new_node->externally_visible = old_node->externally_visible;
+
+ return new_node;
+}
+
+/* Adjust the return type of the given function to its appropriate
+ vector counterpart. Returns a simd array to be used throughout the
+ function as a return value. */
+
+static tree
+simd_clone_adjust_return_type (struct cgraph_node *node)
+{
+ tree fndecl = node->decl;
+ tree orig_rettype = TREE_TYPE (TREE_TYPE (fndecl));
+ unsigned int veclen;
+ tree t;
+
+ /* Adjust the function return type. */
+ if (orig_rettype == void_type_node)
+ return NULL_TREE;
+ TREE_TYPE (fndecl) = build_distinct_type_copy (TREE_TYPE (fndecl));
+ if (INTEGRAL_TYPE_P (TREE_TYPE (TREE_TYPE (fndecl)))
+ || POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (fndecl))))
+ veclen = node->simdclone->vecsize_int;
+ else
+ veclen = node->simdclone->vecsize_float;
+ veclen /= GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (TREE_TYPE (fndecl))));
+ if (veclen > node->simdclone->simdlen)
+ veclen = node->simdclone->simdlen;
+ if (veclen == node->simdclone->simdlen)
+ TREE_TYPE (TREE_TYPE (fndecl))
+ = build_vector_type (TREE_TYPE (TREE_TYPE (fndecl)),
+ node->simdclone->simdlen);
+ else
+ {
+ t = build_vector_type (TREE_TYPE (TREE_TYPE (fndecl)), veclen);
+ t = build_array_type_nelts (t, node->simdclone->simdlen / veclen);
+ TREE_TYPE (TREE_TYPE (fndecl)) = t;
+ }
+ if (!node->definition)
+ return NULL_TREE;
+
+ t = DECL_RESULT (fndecl);
+ /* Adjust the DECL_RESULT. */
+ gcc_assert (TREE_TYPE (t) != void_type_node);
+ TREE_TYPE (t) = TREE_TYPE (TREE_TYPE (fndecl));
+ relayout_decl (t);
+
+ tree atype = build_array_type_nelts (orig_rettype,
+ node->simdclone->simdlen);
+ if (veclen != node->simdclone->simdlen)
+ return build1 (VIEW_CONVERT_EXPR, atype, t);
+
+ /* Set up a SIMD array to use as the return value. */
+ tree retval = create_tmp_var_raw (atype, "retval");
+ gimple_add_tmp_var (retval);
+ return retval;
+}
+
+/* Each vector argument has a corresponding array to be used locally
+ as part of the eventual loop. Create such temporary array and
+ return it.
+
+ PREFIX is the prefix to be used for the temporary.
+
+ TYPE is the inner element type.
+
+ SIMDLEN is the number of elements. */
+
+static tree
+create_tmp_simd_array (const char *prefix, tree type, int simdlen)
+{
+ tree atype = build_array_type_nelts (type, simdlen);
+ tree avar = create_tmp_var_raw (atype, prefix);
+ gimple_add_tmp_var (avar);
+ return avar;
+}
+
+/* Modify the function argument types to their corresponding vector
+ counterparts if appropriate. Also, create one array for each simd
+ argument to be used locally when using the function arguments as
+ part of the loop.
+
+ NODE is the function whose arguments are to be adjusted.
+
+ Returns an adjustment vector that will be filled describing how the
+ argument types will be adjusted. */
+
+static ipa_parm_adjustment_vec
+simd_clone_adjust_argument_types (struct cgraph_node *node)
+{
+ vec<tree> args;
+ ipa_parm_adjustment_vec adjustments;
+
+ if (node->definition)
+ args = ipa_get_vector_of_formal_parms (node->decl);
+ else
+ args = simd_clone_vector_of_formal_parm_types (node->decl);
+ adjustments.create (args.length ());
+ unsigned i, j, veclen;
+ struct ipa_parm_adjustment adj;
+ for (i = 0; i < node->simdclone->nargs; ++i)
+ {
+ memset (&adj, 0, sizeof (adj));
+ tree parm = args[i];
+ tree parm_type = node->definition ? TREE_TYPE (parm) : parm;
+ adj.base_index = i;
+ adj.base = parm;
+
+ node->simdclone->args[i].orig_arg = node->definition ? parm : NULL_TREE;
+ node->simdclone->args[i].orig_type = parm_type;
+
+ if (node->simdclone->args[i].arg_type != SIMD_CLONE_ARG_TYPE_VECTOR)
+ {
+ /* No adjustment necessary for scalar arguments. */
+ adj.op = IPA_PARM_OP_COPY;
+ }
+ else
+ {
+ if (INTEGRAL_TYPE_P (parm_type) || POINTER_TYPE_P (parm_type))
+ veclen = node->simdclone->vecsize_int;
+ else
+ veclen = node->simdclone->vecsize_float;
+ veclen /= GET_MODE_BITSIZE (TYPE_MODE (parm_type));
+ if (veclen > node->simdclone->simdlen)
+ veclen = node->simdclone->simdlen;
+ adj.arg_prefix = "simd";
+ adj.type = build_vector_type (parm_type, veclen);
+ node->simdclone->args[i].vector_type = adj.type;
+ for (j = veclen; j < node->simdclone->simdlen; j += veclen)
+ {
+ adjustments.safe_push (adj);
+ if (j == veclen)
+ {
+ memset (&adj, 0, sizeof (adj));
+ adj.op = IPA_PARM_OP_NEW;
+ adj.arg_prefix = "simd";
+ adj.base_index = i;
+ adj.type = node->simdclone->args[i].vector_type;
+ }
+ }
+
+ if (node->definition)
+ node->simdclone->args[i].simd_array
+ = create_tmp_simd_array (IDENTIFIER_POINTER (DECL_NAME (parm)),
+ parm_type, node->simdclone->simdlen);
+ }
+ adjustments.safe_push (adj);
+ }
+
+ if (node->simdclone->inbranch)
+ {
+ tree base_type
+ = simd_clone_compute_base_data_type (node->simdclone->origin,
+ node->simdclone);
+
+ memset (&adj, 0, sizeof (adj));
+ adj.op = IPA_PARM_OP_NEW;
+ adj.arg_prefix = "mask";
+
+ adj.base_index = i;
+ if (INTEGRAL_TYPE_P (base_type) || POINTER_TYPE_P (base_type))
+ veclen = node->simdclone->vecsize_int;
+ else
+ veclen = node->simdclone->vecsize_float;
+ veclen /= GET_MODE_BITSIZE (TYPE_MODE (base_type));
+ if (veclen > node->simdclone->simdlen)
+ veclen = node->simdclone->simdlen;
+ adj.type = build_vector_type (base_type, veclen);
+ adjustments.safe_push (adj);
+
+ for (j = veclen; j < node->simdclone->simdlen; j += veclen)
+ adjustments.safe_push (adj);
+
+ /* We have previously allocated one extra entry for the mask. Use
+ it and fill it. */
+ struct cgraph_simd_clone *sc = node->simdclone;
+ sc->nargs++;
+ if (node->definition)
+ {
+ sc->args[i].orig_arg
+ = build_decl (UNKNOWN_LOCATION, PARM_DECL, NULL, base_type);
+ sc->args[i].simd_array
+ = create_tmp_simd_array ("mask", base_type, sc->simdlen);
+ }
+ sc->args[i].orig_type = base_type;
+ sc->args[i].arg_type = SIMD_CLONE_ARG_TYPE_MASK;
+ }
+
+ if (node->definition)
+ ipa_modify_formal_parameters (node->decl, adjustments);
+ else
+ {
+ tree new_arg_types = NULL_TREE, new_reversed;
+ bool last_parm_void = false;
+ if (args.length () > 0 && args.last () == void_type_node)
+ last_parm_void = true;
+
+ gcc_assert (TYPE_ARG_TYPES (TREE_TYPE (node->decl)));
+ j = adjustments.length ();
+ for (i = 0; i < j; i++)
+ {
+ struct ipa_parm_adjustment *adj = &adjustments[i];
+ tree ptype;
+ if (adj->op == IPA_PARM_OP_COPY)
+ ptype = args[adj->base_index];
+ else
+ ptype = adj->type;
+ new_arg_types = tree_cons (NULL_TREE, ptype, new_arg_types);
+ }
+ new_reversed = nreverse (new_arg_types);
+ if (last_parm_void)
+ {
+ if (new_reversed)
+ TREE_CHAIN (new_arg_types) = void_list_node;
+ else
+ new_reversed = void_list_node;
+ }
+
+ tree new_type = build_distinct_type_copy (TREE_TYPE (node->decl));
+ TYPE_ARG_TYPES (new_type) = new_reversed;
+ TREE_TYPE (node->decl) = new_type;
+
+ adjustments.release ();
+ }
+ args.release ();
+ return adjustments;
+}
+
+/* Initialize and copy the function arguments in NODE to their
+ corresponding local simd arrays. Returns a fresh gimple_seq with
+ the instruction sequence generated. */
+
+static gimple_seq
+simd_clone_init_simd_arrays (struct cgraph_node *node,
+ ipa_parm_adjustment_vec adjustments)
+{
+ gimple_seq seq = NULL;
+ unsigned i = 0, j = 0, k;
+
+ for (tree arg = DECL_ARGUMENTS (node->decl);
+ arg;
+ arg = DECL_CHAIN (arg), i++, j++)
+ {
+ if (adjustments[j].op == IPA_PARM_OP_COPY)
+ continue;
+
+ node->simdclone->args[i].vector_arg = arg;
+
+ tree array = node->simdclone->args[i].simd_array;
+ if (TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg)) == node->simdclone->simdlen)
+ {
+ tree ptype = build_pointer_type (TREE_TYPE (TREE_TYPE (array)));
+ tree ptr = build_fold_addr_expr (array);
+ tree t = build2 (MEM_REF, TREE_TYPE (arg), ptr,
+ build_int_cst (ptype, 0));
+ t = build2 (MODIFY_EXPR, TREE_TYPE (t), t, arg);
+ gimplify_and_add (t, &seq);
+ }
+ else
+ {
+ unsigned int simdlen = TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg));
+ tree ptype = build_pointer_type (TREE_TYPE (TREE_TYPE (array)));
+ for (k = 0; k < node->simdclone->simdlen; k += simdlen)
+ {
+ tree ptr = build_fold_addr_expr (array);
+ int elemsize;
+ if (k)
+ {
+ arg = DECL_CHAIN (arg);
+ j++;
+ }
+ elemsize
+ = GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (TREE_TYPE (arg))));
+ tree t = build2 (MEM_REF, TREE_TYPE (arg), ptr,
+ build_int_cst (ptype, k * elemsize));
+ t = build2 (MODIFY_EXPR, TREE_TYPE (t), t, arg);
+ gimplify_and_add (t, &seq);
+ }
+ }
+ }
+ return seq;
+}
+
+/* Callback info for ipa_simd_modify_stmt_ops below. */
+
+struct modify_stmt_info {
+ ipa_parm_adjustment_vec adjustments;
+ gimple stmt;
+ /* True if the parent statement was modified by
+ ipa_simd_modify_stmt_ops. */
+ bool modified;
+};
+
+/* Callback for walk_gimple_op.
+
+ Adjust operands from a given statement as specified in the
+ adjustments vector in the callback data. */
+
+static tree
+ipa_simd_modify_stmt_ops (tree *tp, int *walk_subtrees, void *data)
+{
+ struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
+ if (!SSA_VAR_P (*tp))
+ {
+ /* Make sure we treat subtrees as a RHS. This makes sure that
+ when examining the `*foo' in *foo=x, the `foo' get treated as
+ a use properly. */
+ wi->is_lhs = false;
+ wi->val_only = true;
+ if (TYPE_P (*tp))
+ *walk_subtrees = 0;
+ return NULL_TREE;
+ }
+ struct modify_stmt_info *info = (struct modify_stmt_info *) wi->info;
+ struct ipa_parm_adjustment *cand
+ = ipa_get_adjustment_candidate (&tp, NULL, info->adjustments, true);
+ if (!cand)
+ return NULL_TREE;
+
+ tree t = *tp;
+ tree repl = make_ssa_name (TREE_TYPE (t), NULL);
+
+ gimple stmt;
+ gimple_stmt_iterator gsi = gsi_for_stmt (info->stmt);
+ if (wi->is_lhs)
+ {
+ stmt = gimple_build_assign (unshare_expr (cand->new_decl), repl);
+ gsi_insert_after (&gsi, stmt, GSI_SAME_STMT);
+ SSA_NAME_DEF_STMT (repl) = info->stmt;
+ }
+ else
+ {
+ /* You'd think we could skip the extra SSA variable when
+ wi->val_only=true, but we may have `*var' which will get
+ replaced into `*var_array[iter]' and will likely be something
+ not gimple. */
+ stmt = gimple_build_assign (repl, unshare_expr (cand->new_decl));
+ gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
+ }
+
+ if (!useless_type_conversion_p (TREE_TYPE (*tp), TREE_TYPE (repl)))
+ {
+ tree vce = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (*tp), repl);
+ *tp = vce;
+ }
+ else
+ *tp = repl;
+
+ info->modified = true;
+ wi->is_lhs = false;
+ wi->val_only = true;
+ return NULL_TREE;
+}
+
+/* Traverse the function body and perform all modifications as
+ described in ADJUSTMENTS. At function return, ADJUSTMENTS will be
+ modified such that the replacement/reduction value will now be an
+ offset into the corresponding simd_array.
+
+ This function will replace all function argument uses with their
+ corresponding simd array elements, and ajust the return values
+ accordingly. */
+
+static void
+ipa_simd_modify_function_body (struct cgraph_node *node,
+ ipa_parm_adjustment_vec adjustments,
+ tree retval_array, tree iter)
+{
+ basic_block bb;
+ unsigned int i, j;
+
+ /* Re-use the adjustments array, but this time use it to replace
+ every function argument use to an offset into the corresponding
+ simd_array. */
+ for (i = 0, j = 0; i < node->simdclone->nargs; ++i, ++j)
+ {
+ if (!node->simdclone->args[i].vector_arg)
+ continue;
+
+ tree basetype = TREE_TYPE (node->simdclone->args[i].orig_arg);
+ tree vectype = TREE_TYPE (node->simdclone->args[i].vector_arg);
+ adjustments[j].new_decl
+ = build4 (ARRAY_REF,
+ basetype,
+ node->simdclone->args[i].simd_array,
+ iter,
+ NULL_TREE, NULL_TREE);
+ if (adjustments[j].op == IPA_PARM_OP_NONE
+ && TYPE_VECTOR_SUBPARTS (vectype) < node->simdclone->simdlen)
+ j += node->simdclone->simdlen / TYPE_VECTOR_SUBPARTS (vectype) - 1;
+ }
+
+ struct modify_stmt_info info;
+ info.adjustments = adjustments;
+
+ FOR_EACH_BB_FN (bb, DECL_STRUCT_FUNCTION (node->decl))
+ {
+ gimple_stmt_iterator gsi;
+
+ gsi = gsi_start_bb (bb);
+ while (!gsi_end_p (gsi))
+ {
+ gimple stmt = gsi_stmt (gsi);
+ info.stmt = stmt;
+ struct walk_stmt_info wi;
+
+ memset (&wi, 0, sizeof (wi));
+ info.modified = false;
+ wi.info = &info;
+ walk_gimple_op (stmt, ipa_simd_modify_stmt_ops, &wi);
+
+ if (gimple_code (stmt) == GIMPLE_RETURN)
+ {
+ tree retval = gimple_return_retval (stmt);
+ if (!retval)
+ {
+ gsi_remove (&gsi, true);
+ continue;
+ }
+
+ /* Replace `return foo' with `retval_array[iter] = foo'. */
+ tree ref = build4 (ARRAY_REF, TREE_TYPE (retval),
+ retval_array, iter, NULL, NULL);
+ stmt = gimple_build_assign (ref, retval);
+ gsi_replace (&gsi, stmt, true);
+ info.modified = true;
+ }
+
+ if (info.modified)
+ {
+ update_stmt (stmt);
+ if (maybe_clean_eh_stmt (stmt))
+ gimple_purge_dead_eh_edges (gimple_bb (stmt));
+ }
+ gsi_next (&gsi);
+ }
+ }
+}
+
+/* Adjust the argument types in NODE to their appropriate vector
+ counterparts. */
+
+static void
+simd_clone_adjust (struct cgraph_node *node)
+{
+ push_cfun (DECL_STRUCT_FUNCTION (node->decl));
+
+ targetm.simd_clone.adjust (node);
+
+ tree retval = simd_clone_adjust_return_type (node);
+ ipa_parm_adjustment_vec adjustments
+ = simd_clone_adjust_argument_types (node);
+
+ push_gimplify_context ();
+
+ gimple_seq seq = simd_clone_init_simd_arrays (node, adjustments);
+
+ /* Adjust all uses of vector arguments accordingly. Adjust all
+ return values accordingly. */
+ tree iter = create_tmp_var (unsigned_type_node, "iter");
+ tree iter1 = make_ssa_name (iter, NULL);
+ tree iter2 = make_ssa_name (iter, NULL);
+ ipa_simd_modify_function_body (node, adjustments, retval, iter1);
+
+ /* Initialize the iteration variable. */
+ basic_block entry_bb = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
+ basic_block body_bb = split_block_after_labels (entry_bb)->dest;
+ gimple_stmt_iterator gsi = gsi_after_labels (entry_bb);
+ /* Insert the SIMD array and iv initialization at function
+ entry. */
+ gsi_insert_seq_before (&gsi, seq, GSI_NEW_STMT);
+
+ pop_gimplify_context (NULL);
+
+ /* Create a new BB right before the original exit BB, to hold the
+ iteration increment and the condition/branch. */
+ basic_block orig_exit = EDGE_PRED (EXIT_BLOCK_PTR_FOR_FN (cfun), 0)->src;
+ basic_block incr_bb = create_empty_bb (orig_exit);
+ /* The succ of orig_exit was EXIT_BLOCK_PTR_FOR_FN (cfun), with an empty
+ flag. Set it now to be a FALLTHRU_EDGE. */
+ gcc_assert (EDGE_COUNT (orig_exit->succs) == 1);
+ EDGE_SUCC (orig_exit, 0)->flags |= EDGE_FALLTHRU;
+ for (unsigned i = 0;
+ i < EDGE_COUNT (EXIT_BLOCK_PTR_FOR_FN (cfun)->preds); ++i)
+ {
+ edge e = EDGE_PRED (EXIT_BLOCK_PTR_FOR_FN (cfun), i);
+ redirect_edge_succ (e, incr_bb);
+ }
+ edge e = make_edge (incr_bb, EXIT_BLOCK_PTR_FOR_FN (cfun), 0);
+ e->probability = REG_BR_PROB_BASE;
+ gsi = gsi_last_bb (incr_bb);
+ gimple g = gimple_build_assign_with_ops (PLUS_EXPR, iter2, iter1,
+ build_int_cst (unsigned_type_node,
+ 1));
+ gsi_insert_after (&gsi, g, GSI_CONTINUE_LINKING);
+
+ /* Mostly annotate the loop for the vectorizer (the rest is done below). */
+ struct loop *loop = alloc_loop ();
+ cfun->has_force_vect_loops = true;
+ loop->safelen = node->simdclone->simdlen;
+ loop->force_vect = true;
+ loop->header = body_bb;
+ add_bb_to_loop (incr_bb, loop);
+
+ /* Branch around the body if the mask applies. */
+ if (node->simdclone->inbranch)
+ {
+ gimple_stmt_iterator gsi = gsi_last_bb (loop->header);
+ tree mask_array
+ = node->simdclone->args[node->simdclone->nargs - 1].simd_array;
+ tree mask = make_ssa_name (TREE_TYPE (TREE_TYPE (mask_array)), NULL);
+ tree aref = build4 (ARRAY_REF,
+ TREE_TYPE (TREE_TYPE (mask_array)),
+ mask_array, iter1,
+ NULL, NULL);
+ g = gimple_build_assign (mask, aref);
+ gsi_insert_after (&gsi, g, GSI_CONTINUE_LINKING);
+ int bitsize = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (aref)));
+ if (!INTEGRAL_TYPE_P (TREE_TYPE (aref)))
+ {
+ aref = build1 (VIEW_CONVERT_EXPR,
+ build_nonstandard_integer_type (bitsize, 0), mask);
+ mask = make_ssa_name (TREE_TYPE (aref), NULL);
+ g = gimple_build_assign (mask, aref);
+ gsi_insert_after (&gsi, g, GSI_CONTINUE_LINKING);
+ }
+
+ g = gimple_build_cond (EQ_EXPR, mask, build_zero_cst (TREE_TYPE (mask)),
+ NULL, NULL);
+ gsi_insert_after (&gsi, g, GSI_CONTINUE_LINKING);
+ make_edge (loop->header, incr_bb, EDGE_TRUE_VALUE);
+ FALLTHRU_EDGE (loop->header)->flags = EDGE_FALSE_VALUE;
+ }
+
+ /* Generate the condition. */
+ g = gimple_build_cond (LT_EXPR,
+ iter2,
+ build_int_cst (unsigned_type_node,
+ node->simdclone->simdlen),
+ NULL, NULL);
+ gsi_insert_after (&gsi, g, GSI_CONTINUE_LINKING);
+ e = split_block (incr_bb, gsi_stmt (gsi));
+ basic_block latch_bb = e->dest;
+ basic_block new_exit_bb = e->dest;
+ new_exit_bb = split_block (latch_bb, NULL)->dest;
+ loop->latch = latch_bb;
+
+ redirect_edge_succ (FALLTHRU_EDGE (latch_bb), body_bb);
+
+ make_edge (incr_bb, new_exit_bb, EDGE_FALSE_VALUE);
+ /* The successor of incr_bb is already pointing to latch_bb; just
+ change the flags.
+ make_edge (incr_bb, latch_bb, EDGE_TRUE_VALUE); */
+ FALLTHRU_EDGE (incr_bb)->flags = EDGE_TRUE_VALUE;
+
+ gimple phi = create_phi_node (iter1, body_bb);
+ edge preheader_edge = find_edge (entry_bb, body_bb);
+ edge latch_edge = single_succ_edge (latch_bb);
+ add_phi_arg (phi, build_zero_cst (unsigned_type_node), preheader_edge,
+ UNKNOWN_LOCATION);
+ add_phi_arg (phi, iter2, latch_edge, UNKNOWN_LOCATION);
+
+ /* Generate the new return. */
+ gsi = gsi_last_bb (new_exit_bb);
+ if (retval
+ && TREE_CODE (retval) == VIEW_CONVERT_EXPR
+ && TREE_CODE (TREE_OPERAND (retval, 0)) == RESULT_DECL)
+ retval = TREE_OPERAND (retval, 0);
+ else if (retval)
+ {
+ retval = build1 (VIEW_CONVERT_EXPR,
+ TREE_TYPE (TREE_TYPE (node->decl)),
+ retval);
+ retval = force_gimple_operand_gsi (&gsi, retval, true, NULL,
+ false, GSI_CONTINUE_LINKING);
+ }
+ g = gimple_build_return (retval);
+ gsi_insert_after (&gsi, g, GSI_CONTINUE_LINKING);
+
+ /* Handle aligned clauses by replacing default defs of the aligned
+ uniform args with __builtin_assume_aligned (arg_N(D), alignment)
+ lhs. Handle linear by adding PHIs. */
+ for (unsigned i = 0; i < node->simdclone->nargs; i++)
+ if (node->simdclone->args[i].alignment
+ && node->simdclone->args[i].arg_type == SIMD_CLONE_ARG_TYPE_UNIFORM
+ && (node->simdclone->args[i].alignment
+ & (node->simdclone->args[i].alignment - 1)) == 0
+ && TREE_CODE (TREE_TYPE (node->simdclone->args[i].orig_arg))
+ == POINTER_TYPE)
+ {
+ unsigned int alignment = node->simdclone->args[i].alignment;
+ tree orig_arg = node->simdclone->args[i].orig_arg;
+ tree def = ssa_default_def (cfun, orig_arg);
+ if (!has_zero_uses (def))
+ {
+ tree fn = builtin_decl_explicit (BUILT_IN_ASSUME_ALIGNED);
+ gimple_seq seq = NULL;
+ bool need_cvt = false;
+ gimple call
+ = gimple_build_call (fn, 2, def, size_int (alignment));
+ g = call;
+ if (!useless_type_conversion_p (TREE_TYPE (orig_arg),
+ ptr_type_node))
+ need_cvt = true;
+ tree t = make_ssa_name (need_cvt ? ptr_type_node : orig_arg, NULL);
+ gimple_call_set_lhs (g, t);
+ gimple_seq_add_stmt_without_update (&seq, g);
+ if (need_cvt)
+ {
+ t = make_ssa_name (orig_arg, NULL);
+ g = gimple_build_assign_with_ops (NOP_EXPR, t,
+ gimple_call_lhs (g),
+ NULL_TREE);
+ gimple_seq_add_stmt_without_update (&seq, g);
+ }
+ gsi_insert_seq_on_edge_immediate
+ (single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun)), seq);
+
+ entry_bb = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
+ int freq = compute_call_stmt_bb_frequency (current_function_decl,
+ entry_bb);
+ cgraph_create_edge (node, cgraph_get_create_node (fn),
+ call, entry_bb->count, freq);
+
+ imm_use_iterator iter;
+ use_operand_p use_p;
+ gimple use_stmt;
+ tree repl = gimple_get_lhs (g);
+ FOR_EACH_IMM_USE_STMT (use_stmt, iter, def)
+ if (is_gimple_debug (use_stmt) || use_stmt == call)
+ continue;
+ else
+ FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
+ SET_USE (use_p, repl);
+ }
+ }
+ else if (node->simdclone->args[i].arg_type
+ == SIMD_CLONE_ARG_TYPE_LINEAR_CONSTANT_STEP)
+ {
+ tree orig_arg = node->simdclone->args[i].orig_arg;
+ tree def = ssa_default_def (cfun, orig_arg);
+ gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (orig_arg))
+ || POINTER_TYPE_P (TREE_TYPE (orig_arg)));
+ if (!has_zero_uses (def))
+ {
+ iter1 = make_ssa_name (orig_arg, NULL);
+ iter2 = make_ssa_name (orig_arg, NULL);
+ phi = create_phi_node (iter1, body_bb);
+ add_phi_arg (phi, def, preheader_edge, UNKNOWN_LOCATION);
+ add_phi_arg (phi, iter2, latch_edge, UNKNOWN_LOCATION);
+ enum tree_code code = INTEGRAL_TYPE_P (TREE_TYPE (orig_arg))
+ ? PLUS_EXPR : POINTER_PLUS_EXPR;
+ tree addtype = INTEGRAL_TYPE_P (TREE_TYPE (orig_arg))
+ ? TREE_TYPE (orig_arg) : sizetype;
+ tree addcst
+ = build_int_cst (addtype, node->simdclone->args[i].linear_step);
+ g = gimple_build_assign_with_ops (code, iter2, iter1, addcst);
+ gsi = gsi_last_bb (incr_bb);
+ gsi_insert_before (&gsi, g, GSI_SAME_STMT);
+
+ imm_use_iterator iter;
+ use_operand_p use_p;
+ gimple use_stmt;
+ FOR_EACH_IMM_USE_STMT (use_stmt, iter, def)
+ if (use_stmt == phi)
+ continue;
+ else
+ FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
+ SET_USE (use_p, iter1);
+ }
+ }
+
+ calculate_dominance_info (CDI_DOMINATORS);
+ add_loop (loop, loop->header->loop_father);
+ update_ssa (TODO_update_ssa);
+
+ pop_cfun ();
+}
+
+/* If the function in NODE is tagged as an elemental SIMD function,
+ create the appropriate SIMD clones. */
+
+static void
+expand_simd_clones (struct cgraph_node *node)
+{
+ tree attr = lookup_attribute ("omp declare simd",
+ DECL_ATTRIBUTES (node->decl));
+ if (attr == NULL_TREE
+ || node->global.inlined_to
+ || lookup_attribute ("noclone", DECL_ATTRIBUTES (node->decl)))
+ return;
+
+ /* Ignore
+ #pragma omp declare simd
+ extern int foo ();
+ in C, there we don't know the argument types at all. */
+ if (!node->definition
+ && TYPE_ARG_TYPES (TREE_TYPE (node->decl)) == NULL_TREE)
+ return;
+
+ do
+ {
+ /* Start with parsing the "omp declare simd" attribute(s). */
+ bool inbranch_clause_specified;
+ struct cgraph_simd_clone *clone_info
+ = simd_clone_clauses_extract (node, TREE_VALUE (attr),
+ &inbranch_clause_specified);
+ if (clone_info == NULL)
+ continue;
+
+ int orig_simdlen = clone_info->simdlen;
+ tree base_type = simd_clone_compute_base_data_type (node, clone_info);
+ /* The target can return 0 (no simd clones should be created),
+ 1 (just one ISA of simd clones should be created) or higher
+ count of ISA variants. In that case, clone_info is initialized
+ for the first ISA variant. */
+ int count
+ = targetm.simd_clone.compute_vecsize_and_simdlen (node, clone_info,
+ base_type, 0);
+ if (count == 0)
+ continue;
+
+ /* Loop over all COUNT ISA variants, and if !INBRANCH_CLAUSE_SPECIFIED,
+ also create one inbranch and one !inbranch clone of it. */
+ for (int i = 0; i < count * 2; i++)
+ {
+ struct cgraph_simd_clone *clone = clone_info;
+ if (inbranch_clause_specified && (i & 1) != 0)
+ continue;
+
+ if (i != 0)
+ {
+ clone = simd_clone_struct_alloc (clone_info->nargs
+ - clone_info->inbranch
+ + ((i & 1) != 0));
+ simd_clone_struct_copy (clone, clone_info);
+ /* Undo changes targetm.simd_clone.compute_vecsize_and_simdlen
+ and simd_clone_adjust_argument_types did to the first
+ clone's info. */
+ clone->nargs -= clone_info->inbranch;
+ clone->simdlen = orig_simdlen;
+ /* And call the target hook again to get the right ISA. */
+ targetm.simd_clone.compute_vecsize_and_simdlen (node, clone,
+ base_type,
+ i / 2);
+ if ((i & 1) != 0)
+ clone->inbranch = 1;
+ }
+
+ /* simd_clone_mangle might fail if such a clone has been created
+ already. */
+ tree id = simd_clone_mangle (node, clone);
+ if (id == NULL_TREE)
+ continue;
+
+ /* Only when we are sure we want to create the clone actually
+ clone the function (or definitions) or create another
+ extern FUNCTION_DECL (for prototypes without definitions). */
+ struct cgraph_node *n = simd_clone_create (node);
+ if (n == NULL)
+ continue;
+
+ n->simdclone = clone;
+ clone->origin = node;
+ clone->next_clone = NULL;
+ if (node->simd_clones == NULL)
+ {
+ clone->prev_clone = n;
+ node->simd_clones = n;
+ }
+ else
+ {
+ clone->prev_clone = node->simd_clones->simdclone->prev_clone;
+ clone->prev_clone->simdclone->next_clone = n;
+ node->simd_clones->simdclone->prev_clone = n;
+ }
+ change_decl_assembler_name (n->decl, id);
+ /* And finally adjust the return type, parameters and for
+ definitions also function body. */
+ if (node->definition)
+ simd_clone_adjust (n);
+ else
+ {
+ simd_clone_adjust_return_type (n);
+ simd_clone_adjust_argument_types (n);
+ }
+ }
+ }
+ while ((attr = lookup_attribute ("omp declare simd", TREE_CHAIN (attr))));
+}
+
+/* Entry point for IPA simd clone creation pass. */
+
+static unsigned int
+ipa_omp_simd_clone (void)
+{
+ struct cgraph_node *node;
+ FOR_EACH_FUNCTION (node)
+ expand_simd_clones (node);
+ return 0;
+}
+
+namespace {
+
+const pass_data pass_data_omp_simd_clone =
+{
+ SIMPLE_IPA_PASS, /* type */
+ "simdclone", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ ( PROP_ssa | PROP_cfg ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
+};
+
+class pass_omp_simd_clone : public simple_ipa_opt_pass
+{
+public:
+ pass_omp_simd_clone(gcc::context *ctxt)
+ : simple_ipa_opt_pass(pass_data_omp_simd_clone, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return ((flag_openmp || flag_openmp_simd
+ || flag_enable_cilkplus || (in_lto_p && !flag_wpa))
+ && (targetm.simd_clone.compute_vecsize_and_simdlen
+ != NULL)); }
+ unsigned int execute () { return ipa_omp_simd_clone (); }
+};
+
+} // anon namespace
+
+simple_ipa_opt_pass *
+make_pass_omp_simd_clone (gcc::context *ctxt)
+{
+ return new pass_omp_simd_clone (ctxt);
+}
#include "gt-omp-low.h"
if (!COMPARISON_P (comparison))
return NULL_RTX;
- do_pending_stack_adjust ();
+ saved_pending_stack_adjust save;
+ save_pending_stack_adjust (&save);
last = get_last_insn ();
+ do_pending_stack_adjust ();
prepare_cmp_insn (XEXP (comparison, 0), XEXP (comparison, 1),
GET_CODE (comparison), NULL_RTX, unsignedp, OPTAB_WIDEN,
&comparison, &cmode);
}
}
delete_insns_since (last);
+ restore_pending_stack_adjust (&save);
return NULL_RTX;
}
#include "diagnostic.h"
#include "opts.h"
#include "flags.h"
-#include "ggc.h"
#include "tree.h" /* Required by langhooks.h. */
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "langhooks.h"
#include "tm.h" /* Required by rtl.h. */
{
{ "address", SANITIZE_ADDRESS, sizeof "address" - 1 },
{ "thread", SANITIZE_THREAD, sizeof "thread" - 1 },
+ { "leak", SANITIZE_LEAK, sizeof "leak" - 1 },
{ "shift", SANITIZE_SHIFT, sizeof "shift" - 1 },
{ "integer-divide-by-zero", SANITIZE_DIVIDE,
sizeof "integer-divide-by-zero" - 1 },
{ "unreachable", SANITIZE_UNREACHABLE,
sizeof "unreachable" - 1 },
{ "vla-bound", SANITIZE_VLA, sizeof "vla-bound" - 1 },
+ { "return", SANITIZE_RETURN, sizeof "return" - 1 },
{ "null", SANITIZE_NULL, sizeof "null" - 1 },
{ NULL, 0, 0 }
};
if (!opts_set->x_flag_tree_loop_distribute_patterns)
opts->x_flag_tree_loop_distribute_patterns = value;
/* Indirect call profiling should do all useful transformations
- speculative devirutalization does. */
+ speculative devirtualization does. */
if (!opts_set->x_flag_devirtualize_speculatively
&& opts->x_flag_value_profile_transformations)
opts->x_flag_devirtualize_speculatively = false;
#include "coretypes.h"
#include "tm.h"
#include "line-map.h"
-#include "hash-table.h"
#include "input.h"
#include "tree.h"
#include "varasm.h"
#include "expr.h"
#include "basic-block.h"
#include "intl.h"
-#include "ggc.h"
#include "graph.h"
#include "regs.h"
#include "diagnostic-core.h"
#include "coverage.h"
#include "value-prof.h"
#include "tree-inline.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-ssa.h"
#include "tree-cfg.h"
compiled unit. */
INSERT_PASSES_AFTER (all_late_ipa_passes)
NEXT_PASS (pass_ipa_pta);
+ NEXT_PASS (pass_omp_simd_clone);
TERMINATE_PASS_LIST ()
/* These passes are run after IPA passes on every function that is being
#include "params.h"
#include "target.h"
#include "cfgloop.h"
+#include "pointer-set.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "ssa-iterators.h"
#include "tree-ssa-loop-niter.h"
#include "tree-ssa-loop.h"
-#include "ggc.h"
#include "tree-pass.h"
#include "tree-scalar-evolution.h"
#include "cfgloop.h"
-#include "pointer-set.h"
/* real constants: 0, 1, 1-1/REG_BR_PROB_BASE, REG_BR_PROB_BASE,
1/REG_BR_PROB_BASE, 0.5, BB_FREQ_MAX. */
output_buffer::~output_buffer ()
{
- obstack_free (&chunk_obstack, obstack_finish (&chunk_obstack));
- obstack_free (&formatted_obstack, obstack_finish (&formatted_obstack));
+ obstack_free (&chunk_obstack, NULL);
+ obstack_free (&formatted_obstack, NULL);
}
/* A pointer to the formatted diagnostic message. */
#include "coverage.h"
#include "value-prof.h"
#include "tree.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "tree-cfg.h"
int icode = recog (pat, insn,
(GET_CODE (pat) == SET
&& ! reload_completed
- && ! reload_in_progress
- && ! lra_in_progress)
+ && ! reload_in_progress)
? &num_clobbers : 0);
int is_asm = icode < 0 && asm_noperands (PATTERN (insn)) >= 0;
In a CODE_LABEL, part of the two-bit alternate entry field.
1 in a CONCAT is VAL_EXPR_IS_COPIED in var-tracking.c.
1 in a VALUE is SP_BASED_VALUE_P in cselib.c.
- 1 in a SUBREG generated by LRA for reload insns.
- 1 in a CALL for calls instrumented by Pointer Bounds Checker. */
+ 1 in a SUBREG generated by LRA for reload insns. */
unsigned int jump : 1;
/* In a CODE_LABEL, part of the two-bit alternate entry field.
1 in a MEM if it cannot trap.
#define LRA_SUBREG_P(RTX) \
(RTL_FLAG_CHECK1 ("LRA_SUBREG_P", (RTX), SUBREG)->jump)
-/* True if call is instrumented by Pointer Bounds Checker. */
-#define CALL_EXPR_WITH_BOUNDS_P(RTX) \
- (RTL_FLAG_CHECK1 ("CALL_EXPR_WITH_BOUNDS_P", (RTX), CALL)->jump)
-
/* Access various components of an ASM_OPERANDS rtx. */
#define ASM_OPERANDS_TEMPLATE(RTX) XCSTR (RTX, 0, ASM_OPERANDS)
DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_HANDLE_NO_RETURN,
"__asan_handle_no_return",
BT_FN_VOID, ATTR_TMPURE_NOTHROW_LEAF_LIST)
+DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_BEFORE_DYNAMIC_INIT,
+ "__asan_before_dynamic_init",
+ BT_FN_VOID_CONST_PTR, ATTR_NOTHROW_LEAF_LIST)
+DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_AFTER_DYNAMIC_INIT,
+ "__asan_after_dynamic_init",
+ BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST)
/* Thread Sanitizer */
DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_INIT, "__tsan_init",
"__ubsan_handle_builtin_unreachable",
BT_FN_VOID_PTR,
ATTR_COLD_NORETURN_NOTHROW_LEAF_LIST)
+DEF_SANITIZER_BUILTIN(BUILT_IN_UBSAN_HANDLE_MISSING_RETURN,
+ "__ubsan_handle_missing_return",
+ BT_FN_VOID_PTR,
+ ATTR_NORETURN_NOTHROW_LEAF_LIST)
DEF_SANITIZER_BUILTIN(BUILT_IN_UBSAN_HANDLE_VLA_BOUND_NOT_POSITIVE,
"__ubsan_handle_vla_bound_not_positive",
BT_FN_VOID_PTR_PTR,
sched_deps_info->finish_rhs ();
}
+/* Try to group comparison and the following conditional jump INSN if
+ they're already adjacent. This is to prevent scheduler from scheduling
+ them apart. */
+
+static void
+try_group_insn (rtx insn)
+{
+ unsigned int condreg1, condreg2;
+ rtx cc_reg_1;
+ rtx prev;
+
+ if (!any_condjump_p (insn))
+ return;
+
+ targetm.fixed_condition_code_regs (&condreg1, &condreg2);
+ cc_reg_1 = gen_rtx_REG (CCmode, condreg1);
+ prev = prev_nonnote_nondebug_insn (insn);
+ if (!reg_referenced_p (cc_reg_1, PATTERN (insn))
+ || !prev
+ || !modified_in_p (cc_reg_1, prev))
+ return;
+
+ /* Different microarchitectures support macro fusions for different
+ combinations of insn pairs. */
+ if (!targetm.sched.macro_fusion_pair_p
+ || !targetm.sched.macro_fusion_pair_p (prev, insn))
+ return;
+
+ SCHED_GROUP_P (insn) = 1;
+}
+
/* Analyze an INSN with pattern X to find all dependencies. */
static void
sched_analyze_insn (struct deps_desc *deps, rtx x, rtx insn)
can_start_lhs_rhs_p = (NONJUMP_INSN_P (insn)
&& code == SET);
+ /* Group compare and branch insns for macro-fusion. */
+ if (targetm.sched.macro_fusion_p
+ && targetm.sched.macro_fusion_p ())
+ try_group_insn (insn);
+
if (may_trap_p (x))
/* Avoid moving trapping instructions across function calls that might
not always return. */
{
/* And initialize deps_lists. */
sd_init_insn (insn);
+ /* Clean up SCHED_GROUP_P which may be set by last
+ scheduler pass. */
+ if (SCHED_GROUP_P (insn))
+ SCHED_GROUP_P (insn) = 0;
}
deps_analyze_insn (deps, insn);
#include "hash-table.h"
#include "tree.h"
#include "tree-pretty-print.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-fold.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimplify.h"
#include "gimple-iterator.h"
#include "machmode.h"
#include "diagnostic-core.h"
#include "output.h"
-#include "ggc.h"
#include "langhooks.h"
#include "predict.h"
#include "optabs.h"
#include "target.h"
+#include "pointer-set.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "regs.h"
#include "alloc-pool.h"
#include "pretty-print.h"
-#include "pointer-set.h"
#include "params.h"
#include "dumpfile.h"
#include "function.h"
#include "expr.h"
#include "diagnostic-core.h"
-#include "ggc.h"
#include "target.h"
#include "langhooks.h"
#include "regs.h"
#include "cgraph.h"
#include "tree-inline.h"
#include "tree-dump.h"
-#include "gimple.h"
#include "gimplify.h"
/* Data type for the expressions representing sizes of data types.
case MODE_VECTOR_ACCUM:
case MODE_VECTOR_UFRACT:
case MODE_VECTOR_UACCUM:
- case MODE_POINTER_BOUNDS:
mode = mode_for_size (GET_MODE_BITSIZE (mode), MODE_INT, 0);
break;
SET_TYPE_MODE (type, VOIDmode);
break;
- case POINTER_BOUNDS_TYPE:
- SET_TYPE_MODE (type,
- mode_for_size (TYPE_PRECISION (type),
- MODE_POINTER_BOUNDS, 0));
- TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (TYPE_MODE (type)));
- TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (TYPE_MODE (type)));
- break;
-
case OFFSET_TYPE:
TYPE_SIZE (type) = bitsize_int (POINTER_SIZE);
TYPE_SIZE_UNIT (type) = size_int (POINTER_SIZE / BITS_PER_UNIT);
#include "varasm.h"
#include "function.h"
#include "emit-rtl.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "tree-inline.h"
#include "langhooks.h"
#include "hashtab.h"
-#include "ggc.h"
#include "cgraph.h"
#include "diagnostic.h"
#include "timevar.h"
HOOK_VECTOR_END (sched)
+/* Functions relating to OpenMP and Cilk Plus SIMD clones. */
+#undef HOOK_PREFIX
+#define HOOK_PREFIX "TARGET_SIMD_CLONE_"
+HOOK_VECTOR (TARGET_SIMD_CLONE, simd_clone)
+
+DEFHOOK
+(compute_vecsize_and_simdlen,
+"This hook should set @var{vecsize_mangle}, @var{vecsize_int}, @var{vecsize_float}\n\
+fields in @var{simd_clone} structure pointed by @var{clone_info} argument and also\n\
+@var{simdlen} field if it was previously 0.\n\
+The hook should return 0 if SIMD clones shouldn't be emitted,\n\
+or number of @var{vecsize_mangle} variants that should be emitted.",
+int, (struct cgraph_node *, struct cgraph_simd_clone *, tree, int), NULL)
+
+DEFHOOK
+(adjust,
+"This hook should add implicit @code{attribute(target(\"...\"))} attribute\n\
+to SIMD clone @var{node} if needed.",
+void, (struct cgraph_node *), NULL)
+
+DEFHOOK
+(usable,
+"This hook should return -1 if SIMD clone @var{node} shouldn't be used\n\
+in vectorized loops in current function, or non-negative number if it is\n\
+usable. In that case, the smaller the number is, the more desirable it is\n\
+to use it.",
+int, (struct cgraph_node *), NULL)
+
+HOOK_VECTOR_END (simd_clone)
+
/* Functions relating to vectorization. */
#undef HOOK_PREFIX
#define HOOK_PREFIX "TARGET_VECTORIZE_"
(tree exp, rtx target, rtx subtarget, enum machine_mode mode, int ignore),
default_expand_builtin)
-DEFHOOK
-(builtin_chkp_function,
- "This hook allows target to redefine built-in functions used by\n\
-Pointer Bounds Checker for code instrumentation. Hook should return\n\
-fndecl of function implementing generic builtin whose code is\n\
-passed in @var{fcode}. Currently following built-in functions are\n\
-obtained using this hook:\n\
-@deftypefn {Built-in Function} bnd __chkp_bndmk (const void *@var{lb}, size_t @var{size})\n\
-Function code - BUILT_IN_CHKP_BNDMK. This built-in function is used\n\
-by Pointer Bounds Checker to create bound values. @var{lb} holds low\n\
-bound of the resulting bounds. @var{size} holds size of created bounds.\n\
-@end deftypefn\n\
-\n\
-@deftypefn {Built-in Function} void __chkp_bndstx (const void **@var{loc}, const void *@var{ptr}, bnd @var{b})\n\
-Function code - @code{BUILT_IN_CHKP_BNDSTX}. This built-in function is used\n\
-by Pointer Bounds Checker to store bounds @var{b} for pointer @var{ptr}\n\
-stored by address @var{loc}.\n\
-@end deftypefn\n\
-\n\
-@deftypefn {Built-in Function} bnd __chkp_bndldx (const void **@var{loc}, const void *@var{ptr})\n\
-Function code - @code{BUILT_IN_CHKP_BNDLDX}. This built-in function is used\n\
-by Pointer Bounds Checker to get bounds of pointer @var{ptr} loaded by\n\
-address @var{loc}.\n\
-@end deftypefn\n\
-\n\
-@deftypefn {Built-in Function} void __chkp_bndcl (bnd @var{b}, const void *@var{ptr})\n\
-Function code - @code{BUILT_IN_CHKP_BNDCL}. This built-in function is used\n\
-by Pointer Bounds Checker to perform check for pointer @var{ptr} against\n\
-lower bound of bounds @var{b}.\n\
-@end deftypefn\n\
-\n\
-@deftypefn {Built-in Function} void __chkp_bndcu (bnd @var{b}, const void *@var{ptr})\n\
-Function code - @code{BUILT_IN_CHKP_BNDCU}. This built-in function is used\n\
-by Pointer Bounds Checker to perform check for pointer @var{ptr} against\n\
-upper bound of bounds @var{b}.\n\
-@end deftypefn\n\
-\n\
-@deftypefn {Built-in Function} bnd __chkp_bndret (void *@var{ptr})\n\
-Function code - @code{BUILT_IN_CHKP_BNDRET}. This built-in function is used\n\
-by Pointer Bounds Checker to obtain bounds returned by call statement.\n\
-@var{ptr} passed to buil-in is @code{SSA_NAME} returned by call.\n\
-@end deftypefn\n\
-\n\
-@deftypefn {Built-in Function} bnd __chkp_arg_bnd (void *@var{arg})\n\
-Function code - @code{BUILT_IN_CHKP_ARG_BND}. This built-in function is\n\
-used by Pointer Bounds Checker to obtain bounds passed for input argument.\n\
-@var{arg} is default @code{SSA_NAME} of the @code{PARM_DECL} whose\n\
-bounds we want to obtain.\n\
-@end deftypefn\n\
-\n\
-@deftypefn {Built-in Function} bnd __chkp_intersect (bnd @var{b1}, bnd @var{b2})\n\
-Function code - @code{BUILT_IN_CHKP_INTERSECT}. This built-in function\n\
-returns intersection of bounds @var{b1} and @var{b2}.\n\
-@end deftypefn\n\
-\n\
-@deftypefn {Built-in Function} bnd __chkp_narrow (const void *@var{ptr}, bnd @var{b}, size_t @var{s})\n\
-Function code - @code{BUILT_IN_CHKP_NARROW}. This built-in function\n\
-returns intersection of bounds @var{b} and\n\
-[@var{ptr}, @var{ptr} + @var{s} - @code{1}].\n\
-@end deftypefn\n\
-\n\
-@deftypefn {Built-in Function} void *__chkp_set_bounds (const void *@var{ptr}, size_t @var{s})\n\
-Function code - @code{BUILT_IN_CHKP_SET_PTR_BOUNDS}. This built-in function\n\
-returns @var{ptr} with bounds [@var{ptr}, @var{ptr} + @var{s} - @code{1}].\n\
-@end deftypefn\n\
-\n\
-@deftypefn {Built-in Function} size_t __chkp_sizeof (const void *@var{ptr})\n\
-Function code - @code{BUILT_IN_CHKP_SIZEOF}. This built-in function\n\
-returns size of object referenced by @var{ptr}. @var{ptr} is always\n\
-@code{ADDR_EXPR} of @code{VAR_DECL}. This built-in is used by\n\
-Pointer Boudns Checker when bounds of object cannot be computed statically\n\
-(e.g. object has incomplete type).\n\
-@end deftypefn\n\
-\n\
-@deftypefn {Built-in Function} const void *__chkp_extract_lower (bnd @var{b})\n\
-Function code - @code{BUILT_IN_CHKP_EXTRACT_LOWER}. This built-in function\n\
-returns lower bound of bounds @var{b}.\n\
-@end deftypefn\n\
-\n\
-@deftypefn {Built-in Function} const void *__chkp_extract_upper (bnd @var{b})\n\
-Function code - @code{BUILT_IN_CHKP_EXTRACT_UPPER}. This built-in function\n\
-returns upper bound of bounds @var{b}.\n\
-@end deftypefn",
- tree, (unsigned fcode),
- default_builtin_chkp_function)
-
-DEFHOOK
-(chkp_bound_type,
- "Return type to be used for bounds",
- tree, (void),
- default_chkp_bound_type)
-
-DEFHOOK
-(chkp_bound_mode,
- "Return mode to be used for bounds.",
- enum machine_mode, (void),
- default_chkp_bound_mode)
-
/* Select a replacement for a target-specific builtin. This is done
*before* regular type checking, and so allows the target to
implement a crude form of function overloading. The result is a
tree, (tree fndecl),
std_fn_abi_va_list)
-DEFHOOK
-(fn_abi_va_list_bounds_size,
- "This hook returns size for @code{va_list} object in function specified\n\
-by @var{fndecl}. This hook is used by Pointer Bounds Checker to build bounds\n\
-for @code{va_list} object. Return @code{integer_zero_node} if no bounds\n\
-should be used (e.g. @code{va_list} is a scalar pointer to the stack).",
- tree, (tree fndecl),
- default_fn_abi_va_list_bounds_size)
-
/* Get the __builtin_va_list type dependent on input type. */
DEFHOOK
(canonical_va_list_type,
int *pretend_args_size, int second_time),
default_setup_incoming_varargs)
-DEFHOOK
-(load_bounds_for_arg,
- "This hook is used by expand pass to emit insn to load bounds of\n\
-@var{arg} passed in @var{slot}. Expand pass uses this hook in case\n\
-bounds of @var{arg} are not passed in register. If @var{slot} is a\n\
-memory, then bounds are loaded as for regular pointer loaded from\n\
-memory. If @var{slot} is not a memory then @var{slot_no} is an integer\n\
-constant holding number of the target dependent special slot which\n\
-should be used to obtain bounds. Hook returns RTX holding loaded bounds.",
- rtx, (rtx slot, rtx arg, rtx slot_no),
- default_load_bounds_for_arg)
-
-DEFHOOK
-(store_bounds_for_arg,
- "This hook is used by expand pass to emit insns to store @var{bounds} of\n\
-@var{arg} passed in @var{slot}. Expand pass uses this hook in case\n\
-@var{bounds} of @var{arg} are not passed in register. If @var{slot} is a\n\
-memory, then @var{bounds} are stored as for regular pointer stored in\n\
-memory. If @var{slot} is not a memory then @var{slot_no} is an integer\n\
-constant holding number of the target dependent special slot which\n\
-should be used to store @var{bounds}.",
- void, (rtx arg, rtx slot, rtx bounds, rtx slot_no),
- default_store_bounds_for_arg)
-
DEFHOOK
(strict_argument_naming,
"Define this hook to return @code{true} if the location where a function\n\
@code{bool} @code{true}.",
unsigned char, 1)
+/* Return an unsigned int representing the alignment (in bits) of the atomic
+ type which maps to machine MODE. This allows alignment to be overridden
+ as needed. */
+DEFHOOK
+(atomic_align_for_mode,
+"If defined, this function returns an appropriate alignment in bits for an\
+ atomic object of machine_mode @var{mode}. If 0 is returned then the\
+ default alignment for the specified mode is used. ",
+ unsigned int, (enum machine_mode mode),
+ hook_uint_mode_0)
+
DEFHOOK
(atomic_assign_expand_fenv,
"ISO C11 requires atomic compound assignments that may raise floating-point\
struct stdarg_info;
struct spec_info_def;
struct hard_reg_set_container;
+struct cgraph_node;
+struct cgraph_simd_clone;
/* The struct used by the secondary_reload target hook. */
typedef struct secondary_reload_info
#include "target.h"
#include "tm_p.h"
#include "target-def.h"
-#include "ggc.h"
#include "hard-reg-set.h"
#include "regs.h"
#include "reload.h"
#include "recog.h"
#include "intl.h"
#include "opts.h"
-#include "gimple.h"
+#include "tree-ssa-alias.h"
+#include "gimple-expr.h"
#include "gimplify.h"
#include "stringpool.h"
#include "tree-ssanames.h"
-#include "tree-ssa-alias.h"
#include "insn-codes.h"
{
return false;
}
-rtx
-default_load_bounds_for_arg (rtx addr ATTRIBUTE_UNUSED,
- rtx ptr ATTRIBUTE_UNUSED,
- rtx bnd ATTRIBUTE_UNUSED)
-{
- gcc_unreachable ();
-}
-
-void
-default_store_bounds_for_arg (rtx val ATTRIBUTE_UNUSED,
- rtx addr ATTRIBUTE_UNUSED,
- rtx bounds ATTRIBUTE_UNUSED,
- rtx to ATTRIBUTE_UNUSED)
-{
- gcc_unreachable ();
-}
-
-tree
-default_fn_abi_va_list_bounds_size (tree fndecl ATTRIBUTE_UNUSED)
-{
- return integer_zero_node;
-}
/* Default version of canonicalize_comparison. */
return build_va_arg_indirect_ref (addr);
}
-tree
-default_chkp_bound_type (void)
-{
- tree res = make_node (POINTER_BOUNDS_TYPE);
- TYPE_PRECISION (res) = TYPE_PRECISION (size_type_node) * 2;
- layout_type (res);
- return res;
-}
-
-enum machine_mode
-default_chkp_bound_mode (void)
-{
- return VOIDmode;
-}
-
-tree
-default_builtin_chkp_function (unsigned int fcode ATTRIBUTE_UNUSED)
-{
- return NULL_TREE;
-}
-
/* An implementation of TARGET_CAN_USE_DOLOOP_P for targets that do
not support nested low-overhead loops. */
extern void default_atomic_assign_expand_fenv (tree *, tree *, tree *);
extern tree build_va_arg_indirect_ref (tree);
extern tree std_gimplify_va_arg_expr (tree, tree, gimple_seq *, gimple_seq *);
-
-extern rtx default_load_bounds_for_arg (rtx, rtx, rtx);
-extern void default_store_bounds_for_arg (rtx, rtx, rtx, rtx);
-extern tree default_fn_abi_va_list_bounds_size (tree);
-extern tree default_chkp_bound_type (void);
-extern enum machine_mode default_chkp_bound_mode (void);
-extern tree default_builtin_chkp_function (unsigned int);
extern bool can_use_doloop_if_innermost (const widest_int &,
const widest_int &,
unsigned int, bool);
+2013-12-04 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/59355
+ * g++.dg/ipa/pr59355.C: New test.
+
+2013-12-04 Yufeng Zhang <yufeng.zhang@arm.com>
+
+ * gcc.dg/tree-ssa/slsr-39.c: Update.
+ * gcc.dg/tree-ssa/slsr-41.c: New test.
+
+2013-12-03 Adhemerval Zanella <azanella@linux.vnet.ibm.com>
+
+ * gcc.target/powerpc/pr57363.c: New test.
+
+2013-12-03 Wei Mi <wmi@google.com>
+
+ PR rtl-optimization/59020
+ * testsuite/gcc.dg/pr59020.c: New.
+ * testsuite/gcc.dg/macro-fusion-1.c: New.
+ * testsuite/gcc.dg/macro-fusion-2.c: New.
+
+2013-12-03 Yury Gribov <y.gribov@samsung.com>
+
+ PR sanitizer/59063
+ * lib/asan-dg.exp: Don't add anything to flags if libsanitizer
+ has not been found.
+ * lib/ubsan-dg.exp: Likewise. Append to flags also
+ -B${gccpath}/libsanitizer/.
+
+2013-12-03 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
+
+ * gcc.dg/vect/costmodel/ppc/costmodel-slp-34.c: Skip for little
+ endian.
+
+2013-12-03 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR target/59363
+ * gcc.target/i386/pr59363.c: New file.
+
+2013-12-03 Marek Polacek <polacek@redhat.com>
+
+ PR c/59351
+ * gcc.dg/pr59351.c: New test.
+
+2013-12-03 Chung-Ju Wu <jasonwucj@gmail.com>
+
+ * gcc.dg/20020312-2.c: Add __nds32__ case.
+ * gcc.dg/builtin-apply2.c: Skip for nds32*-*-*.
+ * gcc.dg/sibcall-3.c: Expected fail for nds32*-*-*.
+ * gcc.dg/sibcall-4.c: Expected fail for nds32*-*-*.
+ * gcc.dg/stack-usage-1.c (SIZE): Define case for __nds32__.
+ * gcc.dg/torture/pr37868.c: Skip for nds32*-*-*.
+ * gcc.dg/torture/stackalign/builtin-apply-2.c: Skip for nds32*-*-*.
+ * gcc.dg/tree-ssa/20040204-1.c: Expected fail for nds32*-*-*.
+ * gcc.dg/tree-ssa/pr42585.c: Skip for nds32*-*-*.
+ * gcc.dg/tree-ssa/sra-12.c: Skip for nds32*-*-*.
+ * gcc.target/nds32: New nds32 specific directory and testcases.
+ * lib/target-supports.exp (check_profiling_available): Check for
+ nds32*-*-elf.
+
+2013-12-03 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/59362
+ * gcc.c-torture/compile/pr59362.c: New test.
+
+ PR middle-end/59011
+ * gcc.dg/pr59011.c: New test.
+
+ PR target/58864
+ * g++.dg/opt/pr58864.C: New test.
+
+2013-12-02 Jeff Law <law@redhat.com>
+
+ PR tree-optimization/59322
+ * gcc.c-torture/compile/pr59322.c: New test.
+
+2013-12-02 Sriraman Tallam <tmsriram@google.com>
+
+ PR target/58944
+ * testsuite/gcc.target/i386/pr58944.c: New test.
+
+2013-12-02 Joseph Myers <joseph@codesourcery.com>
+
+ PR c/58235
+ * gcc.dg/c90-array-lval-8.c: New test.
+
+2013-12-02 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/59358
+ * gcc.c-torture/execute/pr59358.c: New test.
+
+ PR lto/59326
+ * gcc.target/i386/i386.exp (check_effective_target_avx2): Move to...
+ * lib/target-supports.exp (check_effective_target_avx2): ... here.
+ (check_effective_target_vect_simd_clones): New.
+ * gcc.dg/vect/vect-simd-clone-1.c: Add dg-require-effective-target
+ vect_simd_clones.
+ * gcc.dg/vect/vect-simd-clone-2.c: Likewise.
+ * gcc.dg/vect/vect-simd-clone-3.c: Likewise.
+ * gcc.dg/vect/vect-simd-clone-4.c: Likewise.
+ * gcc.dg/vect/vect-simd-clone-5.c: Likewise.
+ * gcc.dg/vect/vect-simd-clone-6.c: Likewise.
+ * gcc.dg/vect/vect-simd-clone-7.c: Likewise.
+ * gcc.dg/vect/vect-simd-clone-8.c: Likewise.
+ * gcc.dg/vect/vect-simd-clone-9.c: Likewise.
+ * gcc.dg/vect/vect-simd-clone-10.c: Likewise.
+ * gcc.dg/vect/vect-simd-clone-11.c: Likewise.
+ * gcc.dg/vect/vect-simd-clone-12.c: Likewise.
+
+2013-12-02 Bernd Edlinger <bernd.edlinger@hotmail.de>
+
+ * gcc.dg/pr56997-4.c: New testcase.
+
+2013-12-02 Marek Polacek <polacek@redhat.com>
+
+ * c-c++-common/ubsan/vla-1.c: Split the tests into individual
+ functions.
+
+2013-12-02 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/59139
+ * gcc.dg/torture/pr59139.c: New testcase.
+
+2013-12-02 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/opt30.adb: New test.
+
+2013-12-01 Paul Thomas <pault@gcc.gnu.org>
+
+ PR fortran/57354
+ * gfortran.dg/realloc_on_assign_23.f90 : New test
+
+2013-12-01 Paul Thomas <pault@gcc.gnu.org>
+
+ PR fortran/34547
+ * gfortran.dg/null_5.f90 : Include new error.
+ * gfortran.dg/null_6.f90 : Include new error.
+
+2013-11-29 Marek Polacek <polacek@redhat.com>
+
+ PR sanitizer/59331
+ * g++.dg/ubsan/pr59331.C: New test.
+ * g++.dg/ubsan/cxx1y-vla.C: Enable -Wall -Wno-unused-variable.
+ Disable the -w option.
+ * c-c++-common/ubsan/vla-1.c: Likewise.
+ * c-c++-common/ubsan/vla-2.c: Likewise.
+ * c-c++-common/ubsan/vla-3.c: Don't use the -w option.
+
+2013-11-29 Joseph Myers <joseph@codesourcery.com>
+
+ PR c/42262
+ * gcc.dg/c99-init-5.c, gcc.dg/c99-init-6.c: New tests.
+
+2013-11-29 H.J. Lu <hongjiu.lu@intel.com>
+
+ * lib/asan-dg.exp (asan_link_flags): Properly add path to
+ libsanitizer.spec to cflags.
+
+2013-11-29 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/59208
+ * g++.dg/torture/pr59208.C: New testcase.
+
+2013-11-29 Jakub Jelinek <jakub@redhat.com>
+ Yury Gribov <y.gribov@samsung.com>
+
+ PR sanitizer/59063
+ * c-c++-common/asan/pr59063-1.c: New test.
+ * c-c++-common/asan/pr59063-2.c: Likewise.
+ * lib/asan-dg.exp: Add path to libsanitizer.spec to cflags.
+ * lib/ubsan-dg.exp: Likewise.
+
+2013-11-29 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/opt29.ad[sb]: New test.
+
+2013-11-29 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/59338
+ * gcc.dg/torture/pr59338.c: New testcase.
+
+2013-11-29 Jakub Jelinek <jakub@redhat.com>
+
+ PR lto/59326
+ * gcc.dg/vect/vect-simd-clone-12.c: New test.
+ * gcc.dg/vect/vect-simd-clone-12a.c: New test.
+ * gcc.dg/vect/vect-simd-clone-10a.c: Remove extern keywords.
+
+ PR c/59280
+ * c-c++-common/pr59280.c: New test.
+
+2013-11-29 Zhenqiang Chen <zhenqiang.chen@linaro.org>
+
+ * gcc.target/arm/lp1243022.c: Skip target arm-neon.
+
+2013-11-29 Joseph Myers <joseph@codesourcery.com>
+
+ PR c/57574
+ * gcc.dg/inline-35.c: New test.
+
+2013-11-28 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/59297
+ * g++.dg/gomp/pr59297.C: New test.
+
+2013-11-28 Vladimir Makarov <vmakarov@redhat.com>
+
+ PR target/57293
+ * gcc.target/i386/pr57293.c: New.
+
+2013-11-28 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * gcc.target/arm/vrinta-ce.c: New testcase.
+
+2013-11-28 Richard Biener <rguenther@suse.de>
+
+ PR lto/59323
+ * gcc.dg/lto/pr59323-2_0.c: New testcase.
+
+2013-11-28 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/59330
+ * gcc.dg/torture/pr59330.c: New testcase.
+
+2013-11-28 Richard Biener <rguenther@suse.de>
+
+ PR lto/59323
+ * gcc.dg/lto/pr59323_0.c: New testcase.
+
+2013-11-28 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/57393
+ PR tree-optimization/58018
+ PR tree-optimization/58131
+ * gcc.dg/torture/pr57393-1.c: New test.
+ * gcc.dg/torture/pr57393-2.c: New test.
+ * gcc.dg/torture/pr57393-3.c: New test.
+ * gcc.dg/torture/pr58018.c: New test.
+ * gcc.dg/torture/pr58131.c: New test.
+ * gfortran.dg/pr57393-1.f90: New test.
+ * gfortran.dg/pr57393-2.f90: New test.
+
+2013-11-27 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
+
+ * gfortran.dg/nan_7.f90: Disable for little endian PowerPC.
+
+2013-11-27 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc.dg/guality/param-3.c: New test.
+
+2013-11-27 Uros Bizjak <ubizjak@gmail.com>
+ Ganesh Gopalasubramanian <Ganesh.Gopalasubramanian@amd.com>
+
+ PR target/56788
+ * gcc.target/i386/xop-frczX.c: New test.
+
+2013-11-27 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/59014
+ * gcc.c-torture/execute/pr59014-2.c: New test.
+
+2013-11-27 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58647
+ * g++.dg/parse/crash66.C: New.
+
+2013-11-27 Kenneth Zadeck <zadeck@naturalbridge.com>
+
+ * gcc.dg/c90-const-expr-8.c: Look for overflow on INT_MIN % -1.
+ * gcc.dg/c99-const-expr-8.c: Look for overflow on INT_MIN % -1.
+
+2013-11-27 Marek Polacek <polacek@redhat.com>
+
+ PR sanitizer/59306
+ * g++.dg/ubsan/pr59306.C: New test.
+
+2013-11-27 Aldy Hernandez <aldyh@redhat.com>
+ Jakub Jelinek <jakub@redhat.com>
+
+ * g++.dg/gomp/declare-simd-1.C (f38): Make sure
+ simdlen is a power of two.
+ * gcc.dg/gomp/simd-clones-2.c: Compile on all targets.
+ Remove -msse2. Adjust regexps for name mangling changes.
+ * gcc.dg/gomp/simd-clones-3.c: Likewise.
+ * gcc.dg/vect/vect-simd-clone-1.c: New test.
+ * gcc.dg/vect/vect-simd-clone-2.c: New test.
+ * gcc.dg/vect/vect-simd-clone-3.c: New test.
+ * gcc.dg/vect/vect-simd-clone-4.c: New test.
+ * gcc.dg/vect/vect-simd-clone-5.c: New test.
+ * gcc.dg/vect/vect-simd-clone-6.c: New test.
+ * gcc.dg/vect/vect-simd-clone-7.c: New test.
+ * gcc.dg/vect/vect-simd-clone-8.c: New test.
+ * gcc.dg/vect/vect-simd-clone-9.c: New test.
+ * gcc.dg/vect/vect-simd-clone-10.c: New test.
+ * gcc.dg/vect/vect-simd-clone-10.h: New file.
+ * gcc.dg/vect/vect-simd-clone-10a.c: New file.
+ * gcc.dg/vect/vect-simd-clone-11.c: New test.
+
+2013-11-27 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ * gcc.dg/cilk-plus/cilk-plus.exp: Append to ld_library_path.
+ Call set_ld_library_path_env_vars.
+ * g++.dg/cilk-plus/cilk-plus.exp: Likewise.
+
+2013-11-27 Tom de Vries <tom@codesourcery.com>
+ Marc Glisse <marc.glisse@inria.fr>
+
+ PR c++/59032
+ * c-c++-common/pr59032.c: New testcase.
+
+2013-11-27 Tom de Vries <tom@codesourcery.com>
+ Marc Glisse <marc.glisse@inria.fr>
+
+ PR middle-end/59037
+ * c-c++-common/pr59037.c: New testcase.
+
+2013-11-27 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc.c-torture/execute/20131127-1.c: New test.
+
+2013-11-27 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/59288
+ * gcc.dg/torture/pr59288.c: New testcase.
+
+2013-11-27 Marek Polacek <polacek@redhat.com>
+
+ * c-c++-common/ubsan/undefined-1.c: New test.
+
+2013-11-26 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/59014
+ * gcc.c-torture/execute/pr59014.c: New test.
+
+ PR target/59229
+ * gcc.c-torture/execute/pr59229.c: New test.
+
+ PR rtl-optimization/59166
+ * gcc.dg/torture/pr59166.c: New test.
+
+ PR c++/58874
+ * g++.dg/gomp/pr58874.C: New test.
+
+ PR middle-end/59150
+ * g++.dg/gomp/pr59150.C: New test.
+
+ PR middle-end/59152
+ * c-c++-common/gomp/pr59152.c: New test.
+
+2013-11-26 Uros Bizjak <ubizjak@gmail.com>
+
+ * gcc.dg/gomp/openmp-simd-1.c: Cleanup original tree dump.
+ * gcc.dg/gomp/openmp-simd-2.c: Ditto.
+ * g++.dg/gomp/openmp-simd-1.C: Ditto.
+ * g++.dg/gomp/openmp-simd-2.C: Ditto.
+ * gfortran.dg/c_loc_test_22.f90: Ditto.
+ * gcc.dg/tree-ssa/attr-alias-2.c: Cleanup optimized tree dump.
+ * gcc.dg/tree-ssa/isolate-5.c: Ditto.
+ * gcc.dg/tree-ssa/pr57361.c: Cleanup dse1 tree dump.
+ * gcc.dg/vect/vect-124.c: Cleanup vect tree dump.
+ * gcc.dg/pr57518.c: Cleanup ira rtl dump.
+ * gcc.dg/tree-prof/cold_partition_label.c: Cleanup saved temps.
+
+2013-11-26 Yufeng Zhang <yufeng.zhang@arm.com>
+
+ * gcc.target/arm/20131120.c: New test.
+
+2013-11-26 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/59245
+ * gcc.dg/torture/pr59245.c: New testcase.
+
+2013-11-26 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ PR target/59290
+ * gcc.target/arm/negdi-2.c: Scan more general register names.
+
+2013-11-26 Terry Guo <terry.guo@arm.com>
+
+ * gcc.target/arm/thumb1-pic-high-reg.c: New case.
+ * gcc.target/arm/thumb1-pic-single-base.c: New case.
+
+2013-11-26 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58700
+ * g++.dg/parse/bitfield4.C: New.
+
+2013-11-26 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/59287
+ * gcc.dg/tree-ssa/alias-29.c: New testcase.
+
+2013-11-25 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/54485
+ * g++.dg/other/default8.C: New.
+ * g++.dg/tc1/dr217.C: Remove xfail.
+ * g++.dg/other/default5.C: Adjust.
+ * g++.old-deja/g++.mike/p1989.C: Likewise.
+
+2013-11-25 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58607
+ * g++.dg/cpp0x/constexpr-ice9.C: New.
+
+2013-11-25 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58810
+ * g++.dg/other/cv_func3.C: New.
+ * g++.dg/other/cv_func.C: Adjust.
+ * g++.dg/parse/fn-typedef2.C: Likewise.
+
+2013-11-25 Marek Polacek <polacek@redhat.com>
+
+ PR sanitizer/59250
+ * g++.dg/ubsan/pr59250.C: New test.
+
+2013-11-25 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/59143
+ * gfortran.dg/typebound_proc_30.f90: New.
+
+2013-11-25 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/59080
+ * g++.dg/cpp0x/initlist75.C: New.
+
+ PR c++/59096
+ * g++.dg/cpp0x/gen-attrs-57.C: New.
+
+2013-11-25 Adam Butcher <adam@jessamine.co.uk>
+
+ PR c++/59112
+ PR c++/59113
+ * g++.dg/cpp1y/pr58533.C: Updated testcase.
+ * g++.dg/cpp1y/pr59112.C: New testcase.
+ * g++.dg/cpp1y/pr59113.C: New testcase.
+
+2013-11-25 Terry Guo <terry.guo@arm.com>
+
+ * gcc.target/arm/thumb2-slow-flash-data.c: New.
+
+2013-11-23 Uros Bizjak <ubizjak@gmail.com>
+
+ * gcc.dg/float-exact-1.c: Use dg-add-options ieee.
+ [LDBL_MANT_DIG == 113]: Fix wrong variable name.
+
+2013-11-23 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/59228
+ * gfortran.dg/asynchronous_4.f90: New.
+
+2013-11-22 Jakub Jelinek <jakub@redhat.com>
+
+ * c-c++-common/asan/no-redundant-instrumentation-7.c: Fix
+ cleanup-tree-dump directive.
+
+2013-11-22 Jan Hubicka <jh@suse.cz>
+
+ * gcc.dg/20081223-1.c: Add -ffat-lto-objects.
+ * gcc.dg/vect/vect.exp: Add -ffat-lto-objects.
+
+2013-11-22 Jakub Jelinek <jakub@redhat.com>
+
+ * g++.dg/ubsan/return-1.C: New test.
+ * g++.dg/ubsan/return-2.C: New test.
+
+ * c-c++-common/asan/no-redundant-instrumentation-1.c: Tweak to avoid
+ optimizing away some __asan_report* calls.
+
+2013-11-22 Martin Jambor <mjambor@suse.cz>
+
+ * gcc.dg/pr10474.c: Also test ppc64.
+ * gcc.dg/ira-shrinkwrap-prep-1.c: Also test ppc64, change all ints
+ to longs.
+ * gcc.dg/ira-shrinkwrap-prep-2.c: Likewise.
+
+2013-11-22 Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ PR target/59054
+ * gcc.target/powerpc/direct-move.h (VSX_REG_ATTR): Allow test to
+ specify an appropriate register class for VSX operations.
+ (load_vsx): Use it.
+ (load_gpr_to_vsx): Likewise.
+ (load_vsx_to_gpr): Likewise.
+ * gcc.target/powerpc/direct-move-vint1.c: Use an appropriate
+ register class for VSX registers that the type can handle. Remove
+ checks for explicit number of instructions generated, just check
+ if the instruction is generated.
+ * gcc.target/powerpc/direct-move-vint2.c: Likewise.
+ * gcc.target/powerpc/direct-move-float1.c: Likewise.
+ * gcc.target/powerpc/direct-move-float2.c: Likewise.
+ * gcc.target/powerpc/direct-move-double1.c: Likewise.
+ * gcc.target/powerpc/direct-move-double2.c: Likewise.
+ * gcc.target/powerpc/direct-move-long1.c: Likewise.
+ * gcc.target/powerpc/direct-move-long2.c: Likewise.
+
+ * gcc.target/powerpc/pr59054.c: Remove duplicate code.
+
+ * gcc.target/powerpc/bool3-av.c: Limit to 64-bit mode for now.
+ * gcc.target/powerpc/bool3-p7.c: Likewise.
+ * gcc.target/powerpc/bool3-p8.c: Likewise.
+
+ * gcc.target/powerpc/p8vector-ldst.c: Just check that the
+ appropriate instructions are generated, don't check the count.
+
+2013-11-22 Richard Earnshaw <rearnsha@arm.com>
+
+ PR target/59216
+ * gcc.target/arm/negdi-4.c: Delete invalid test.
+ * gcc.dg/torture/pr59216.c: New test.
+
+2013-11-22 Alex Velenko <Alex.Velenko@arm.com>
+
+ * gcc.target/aarch64/vmov_n_1.c: New testcase.
+
2013-11-22 Richard Biener <rguenther@suse.de>
* gcc.dg/torture/20131122-0.c: New testcase.
/* { dg-do compile } */
/* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */
-static char tab[4] = {0};
+extern char tab[4];
static int
test0 ()
return t0 + t1;
}
-static int
-test1 ()
+__attribute__((noinline, noclone)) static int
+test1 (int i)
{
+ char foo[4] = {};
+
/*__builtin___asan_report_store1 called 1 time here to instrument
the initialization. */
- char foo[4] = {1};
+ foo[i] = 1;
/*__builtin___asan_report_store1 called 2 times here to instrument
the store to the memory region of tab. */
/* There are 2 calls to __builtin___asan_report_store1 and 2 calls
to __builtin___asan_report_load1 to instrument the store to
(subset of) the memory region of tab. */
- __builtin_memcpy (&tab[1], foo, 3);
+ __builtin_memcpy (&tab[1], foo + i, 3);
/* This should not generate a __builtin___asan_report_load1 because
the reference to tab[1] has been already instrumented above. */
int
main ()
{
- return test0 () && test1 ();
+ return test0 () && test1 (0);
}
/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store1" 7 "asan0" } } */
/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load" 6 "asan0" } } */
/* { dg-final { scan-tree-dump-not "__builtin___asan_report_store" "asan0" } } */
-/* { dg-final { cleanup-tree-dump "asan" } } */
+/* { dg-final { cleanup-tree-dump "asan0" } } */
--- /dev/null
+/* { dg-do run } */
+
+#include <time.h>
+static int weak_gettime (clockid_t clk_id, struct timespec *tp)
+ __attribute__((__weakref__("clock_gettime")));
+int main() {
+ if (!clock_gettime)
+ return 0;
+ struct timespec ts;
+ return weak_gettime(CLOCK_MONOTONIC, &ts);
+}
--- /dev/null
+/* { dg-do run } */
+/* { dg-options "-static-libasan" } */
+
+#include <time.h>
+static int weak_gettime (clockid_t clk_id, struct timespec *tp)
+ __attribute__((__weakref__("clock_gettime")));
+int main() {
+ if (!clock_gettime)
+ return 0;
+ struct timespec ts;
+ return weak_gettime(CLOCK_MONOTONIC, &ts);
+}
--- /dev/null
+/* PR middle-end/59152 */
+/* { dg-do compile } */
+/* { dg-options "-fopenmp -fipa-pure-const" } */
+
+extern int b[];
+void
+foo (void)
+{
+ unsigned long v1, v2, v3;
+ #pragma omp parallel for schedule(static, 32) collapse(3)
+ for (v1 = 0; v1 < 20; v1 += 2)
+ for (v2 = __LONG_MAX__; v2 > __LONG_MAX__ - 30; v2 -= 3)
+ for (v3 = 10; v3 > 0; v3--)
+ #pragma omp atomic
+ b[v3]++;
+}
+
+void
+bar (void)
+{
+ unsigned long v1, v2, v3;
+ #pragma omp parallel for schedule(static) collapse(3)
+ for (v1 = 0; v1 < 20; v1 += 2)
+ for (v2 = __LONG_MAX__; v2 > __LONG_MAX__ - 30; v2 -= 3)
+ for (v3 = 10; v3 > 0; v3--)
+ #pragma omp atomic
+ b[v3]++;
+}
+
+void
+baz (void)
+{
+ unsigned long v1, v2, v3;
+ #pragma omp parallel for schedule(runtime) collapse(3)
+ for (v1 = 0; v1 < 20; v1 += 2)
+ for (v2 = __LONG_MAX__; v2 > __LONG_MAX__ - 30; v2 -= 3)
+ for (v3 = 10; v3 > 0; v3--)
+ #pragma omp atomic
+ b[v3]++;
+}
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+void
+foo()
+{
+ float v __attribute__((vector_size(8)));
+ v++;
+}
+
+void
+foo2 ()
+{
+ float v __attribute__((vector_size(8)));
+ ++v;
+}
+
+void
+foo3 ()
+{
+ float v __attribute__((vector_size(8)));
+ v--;
+}
+
+void
+foo4 ()
+{
+ float v __attribute__((vector_size(8)));
+ --v;
+}
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+
+typedef int v4si __attribute__ ((vector_size (16)));
+
+int
+main (int argc, char** argv)
+{
+ v4si x = {0,1,2,3};
+ x = (v4si) {(x)[3], (x)[2], (x)[1], (x)[0]};
+ return x[4];
+}
--- /dev/null
+/* PR c/59280 */
+/* { dg-do compile } */
+
+void bar (char *) __attribute__((constructor(foo))); /* { dg-error "constructor priorities must be integers|was not declared|constructor priorities are not supported" } */
--- /dev/null
+/* { dg-do run } */
+/* { dg-options "-fsanitize=undefined" } */
+/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */
+
+int
+foo (int x, int y)
+{
+ const int z = 2;
+ if (z & 1)
+ return x << y;
+ return 0;
+}
+
+int
+bar (int x, int y)
+{
+ return x + y;
+}
+
+int
+main (void)
+{
+ foo (3, 2);
+ bar (12, 42);
+ return 0;
+}
/* { dg-do run } */
-/* { dg-options "-fsanitize=vla-bound -w" } */
+/* { dg-options "-fsanitize=vla-bound -Wall -Wno-unused-variable" } */
-static int
+typedef long int V;
+int x = -1;
+double di = -3.2;
+V v = -6;
+
+static int __attribute__ ((noinline, noclone))
bar (void)
{
- return -42;
+ return -4;
}
-typedef long int V;
-int
-main (void)
+static void __attribute__ ((noinline, noclone))
+fn1 (void)
{
- int x = -1;
- double di = -3.2;
- V v = -666;
-
int a[x];
- int aa[x][x];
- int aaa[x][x][x];
+}
+
+static void __attribute__ ((noinline, noclone))
+fn2 (void)
+{
+ int a[x][x];
+}
+
+static void __attribute__ ((noinline, noclone))
+fn3 (void)
+{
+ int a[x][x][x];
+}
+
+static void __attribute__ ((noinline, noclone))
+fn4 (void)
+{
int b[x - 4];
+}
+
+static void __attribute__ ((noinline, noclone))
+fn5 (void)
+{
int c[(int) di];
+}
+
+static void __attribute__ ((noinline, noclone))
+fn6 (void)
+{
int d[1 + x];
+}
+
+static void __attribute__ ((noinline, noclone))
+fn7 (void)
+{
int e[1 ? x : -1];
+}
+
+static void __attribute__ ((noinline, noclone))
+fn8 (void)
+{
int f[++x];
+}
+
+static void __attribute__ ((noinline, noclone))
+fn9 (void)
+{
int g[(signed char) --x];
+}
+
+static void __attribute__ ((noinline, noclone))
+fn10 (void)
+{
int h[(++x, --x, x)];
+}
+
+static void __attribute__ ((noinline, noclone))
+fn11 (void)
+{
int i[v];
+}
+
+static void __attribute__ ((noinline, noclone))
+fn12 (void)
+{
int j[bar ()];
+}
+int
+main (void)
+{
+ fn1 ();
+ fn2 ();
+ fn3 ();
+ fn4 ();
+ fn5 ();
+ fn6 ();
+ fn7 ();
+ fn8 ();
+ fn9 ();
+ fn10 ();
+ fn11 ();
+ fn12 ();
return 0;
}
/* { dg-output "\[^\n\r]*variable length array bound evaluates to non-positive value 0(\n|\r\n|\r)" } */
/* { dg-output "\[^\n\r]*variable length array bound evaluates to non-positive value -1(\n|\r\n|\r)" } */
/* { dg-output "\[^\n\r]*variable length array bound evaluates to non-positive value -1(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*variable length array bound evaluates to non-positive value -666(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*variable length array bound evaluates to non-positive value -42(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*variable length array bound evaluates to non-positive value -6(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*variable length array bound evaluates to non-positive value -4(\n|\r\n|\r)" } */
/* { dg-do run } */
-/* { dg-options "-fsanitize=vla-bound -w" } */
+/* { dg-options "-fsanitize=vla-bound -Wall -Wno-unused-variable" } */
int
main (void)
/* { dg-do run } */
-/* { dg-options "-fsanitize=vla-bound -w" } */
+/* { dg-options "-fsanitize=vla-bound" } */
/* Don't instrument the arrays here. */
int
set library_var [get_multilibs]
# Pointing the ld_library_path to the Cilk Runtime library binaries.
-set ld_library_path "${library_var}/libcilkrts/.libs"
+append ld_library_path ":${library_var}/libcilkrts/.libs"
+set_ld_library_path_env_vars
global TEST_EXTRA_LIBS
set TEST_EXTRA_LIBS "-L${library_var}/libcilkrts/.libs"
--- /dev/null
+// PR c++/58607
+// { dg-do compile { target c++11 } }
+
+struct A
+{
+ constexpr A() { i; } // { dg-error "declared|empty body" }
+};
--- /dev/null
+// PR c++/59096
+// { dg-do compile { target c++11 } }
+
+template<typename T> struct A
+{
+ typedef T B [[mode]]; // { dg-warning "ignored" }
+};
+
+A<int>::B b;
--- /dev/null
+// PR c++/59080
+// { dg-require-effective-target c++11 }
+
+#include <initializer_list>
+
+auto foo[] = {}; // { dg-error "auto|unable to deduce" }
void foo()
{
- void (*fp)(auto); // { dg-error "template" }
+ void (*fp)(auto); // { dg-error "auto|not permitted" }
}
--- /dev/null
+// { dg-do compile }
+// { dg-options "-std=gnu++1y" }
+
+// PR c++/59112
+
+void foo()
+{
+ struct A
+ {
+ A(auto) {} // { dg-error "auto|not permitted" }
+ };
+}
--- /dev/null
+// { dg-do compile }
+// { dg-options "-std=gnu++1y" }
+
+// PR c++/59113
+
+void foo()
+{
+ void bar(auto) {} // { dg-error "function-definition|auto|not permitted" }
+}
+
+auto i = 0;
void
f38 (D &d)
{
- d.f37 <12> (6);
+ d.f37 <16> (6);
}
/* { dg-final { scan-tree-dump-not "omp teams" "original" } } */
/* { dg-final { scan-tree-dump-not "omp target" "original" } } */
/* { dg-final { scan-tree-dump-not "omp parallel" "original" } } */
+/* { dg-final { cleanup-tree-dump "original" } } */
/* { dg-final { scan-tree-dump-times "pragma omp simd safelen\\(64\\)" 1 "original" } } */
/* { dg-final { scan-tree-dump-not "omp parallel" "original" } } */
/* { dg-final { scan-tree-dump-not "omp for" "original" } } */
+/* { dg-final { cleanup-tree-dump "original" } } */
--- /dev/null
+// PR c++/58874
+// { dg-do compile }
+// { dg-options "-fopenmp" }
+
+struct A
+{
+ template<int> struct B
+ {
+ #pragma omp declare reduction (x : int : omp_out |= omp_in)
+ };
+};
+
+#pragma omp declare reduction (y : long : omp_out |= omp_in) \
+ initializer (omp_priv = 0)
--- /dev/null
+// PR middle-end/59150
+// { dg-do compile }
+// { dg-options "-O -fopenmp-simd -fno-tree-ccp -fno-tree-copy-prop -fno-tree-dce" }
+
+#pragma omp declare reduction (foo: int: omp_out += omp_in) initializer (omp_priv = 0)
+
+int
+foo ()
+{
+ int i, v, &u = v;
+ #pragma omp simd reduction (foo:u)
+ for (i = 0; i < 1024; i++)
+ u = i;
+ return u;
+}
+
+int
+bar ()
+{
+ int i, v, &u = v;
+ #pragma omp simd reduction (foo:u) safelen(1)
+ for (i = 0; i < 1024; i++)
+ u = i;
+ return u;
+}
--- /dev/null
+// PR c++/59297
+// { dg-do compile }
+// { dg-options "-fopenmp" }
+
+template <typename T>
+struct A
+{
+ ~A ();
+ const T &operator[] (int) const;
+};
+
+struct B
+{
+ int &operator () (A <int>);
+};
+
+void
+foo (B &x, int &z)
+{
+ A<A<int> > y;
+ #pragma omp atomic
+ x (y[0]) += 1;
+ #pragma omp atomic
+ z += x(y[1]);
+}
--- /dev/null
+// PR c++/59031
+// { dg-do compile }
+// { dg-options "-fdump-tree-gimple " }
+class B {
+ public:
+ virtual int add (int a, int b) {return a+ b;}
+};
+
+class D : public B {
+};
+
+int foo (int a, int b) {
+ D d;
+ return d.add(a, b);
+}
+// { dg-final { scan-tree-dump-not "OBJ_TYPE_REF" "gimple" } }
+// { dg-final { cleanup-tree-dump "gimple" } }
--- /dev/null
+// PR tree-optimization/59355
+// { dg-do compile }
+// { dg-options "-O2 -fno-devirtualize" }
+
+struct S
+{
+ virtual void bar ();
+};
+
+void
+foo (S *s)
+{
+ s->bar ();
+}
--- /dev/null
+// PR target/58864
+// { dg-do compile }
+// { dg-options "-Os" }
+// { dg-additional-options "-march=i686" { target { { i?86-*-* x86_64-*-* } && ia32 } } }
+
+struct A { A (); ~A (); };
+struct B { B (); };
+
+float d, e;
+
+void
+foo ()
+{
+ A a;
+ float c = d;
+ while (1)
+ {
+ B b;
+ e = c ? -c : 0;
+ }
+}
typedef int FIC(int) const;
typedef int FI(int);
-FIC f; // { dg-error "qualified" }
+FIC f; // { dg-error "cv-qualifier" }
struct S {
FIC f; // OK
--- /dev/null
+// PR c++/58810
+
+typedef int F() const;
+
+F f; // { dg-error "cv-qualifier" }
+
+struct A
+{
+ friend F f; // { dg-error "cv-qualifier" }
+};
void F2(int, int, int = 0);
};
-template<int N> void B<N>::F1(int, int = 0, int) {}
-template<int N> void B<N>::F2(int = 0, int, int) {} // { dg-error "default" }
+template<int N> void B<N>::F1(int, int = 0, int) {} // { dg-error "default arguments" }
+template<int N> void B<N>::F2(int = 0, int, int) {} // { dg-error "default arguments|parameter 2" }
--- /dev/null
+// PR c++54485
+
+template<typename T>
+class K1
+{
+ int fn(int, int);
+ int gn(int, int);
+};
+
+template<typename T>
+int K1<T>::fn (int a, int b = 3) // { dg-error "default arguments" }
+{
+ return a - b;
+}
+
+template<typename T>
+int K1<T>::gn (int a = 1, int b = 3) // { dg-error "default arguments" }
+{
+ return a - b;
+}
+
+template<typename T>
+class K2
+{
+ template<typename U>
+ int fn(int, int);
+ template<typename U>
+ int gn(int, int);
+};
+
+template<typename T>
+template<typename U>
+int K2<T>::fn (int a, int b = 3) // { dg-error "default arguments" }
+{
+ return a - b;
+}
+
+template<typename T>
+template<typename U>
+int K2<T>::gn (int a = 1, int b = 3) // { dg-error "default arguments" }
+{
+ return a - b;
+}
--- /dev/null
+// PR c++/58700
+
+struct A
+{
+ static int : 4; // { dg-error "bit-field" }
+};
--- /dev/null
+// PR c++/58647
+
+struct A
+{
+ static void foo();
+};
+
+template<typename> void bar()
+{
+ A().foo;
+}
typedef void V;
typedef V ft() const;
-ft f; // { dg-error "qualified" }
+ft f; // { dg-error "cv-qualifier" }
#include "stringpool.h"
#include "toplev.h"
#include "basic-block.h"
+#include "pointer-set.h"
+#include "hash-table.h"
+#include "vec.h"
+#include "ggc.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-fold.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "tree.h"
};
template <class T>
-void S<T>::foo (int = 0) // { dg-error "" "default arguments for parameters of member functions of class templates can be specified in the initial declaration only" { xfail *-*-* } }
+void S<T>::foo (int = 0) // { dg-error "" "default arguments for parameters of member functions of class templates can be specified in the initial declaration only" }
{ }
--- /dev/null
+// { dg-do compile }
+class A {
+public:
+ A();
+ A(int *);
+};
+class B {};
+class C : B {
+public:
+ virtual void m_fn1();
+ void operator+=(int) { m_fn1(); }
+};
+enum DebuggerType {};
+C a;
+DebuggerType b;
+void operator==(A &, const A &);
+static A get_dbx_doc(A &p1) { p1 == 0; }
+
+void add_button() {
+ A c;
+ switch (b)
+ case 0:
+ get_dbx_doc(c);
+ a += 0;
+}
/* { dg-do run } */
-/* { dg-options "-fsanitize=vla-bound -w -std=c++1y" } */
+/* { dg-options "-fsanitize=vla-bound -Wall -Wno-unused-variable -std=c++1y" } */
/* { dg-shouldfail "ubsan" } */
int
--- /dev/null
+// PR sanitizer/59250
+// { dg-do compile }
+// { dg-options "-fsanitize=undefined" }
+// { dg-skip-if "" { *-*-* } { "-flto" } { "" } }
+
+struct E {
+ int i;
+};
+
+struct S {
+ const char *s;
+ S (const char *);
+ static E *e;
+};
+
+S::S (const char *) : s (0)
+{
+ e = new E ();
+}
--- /dev/null
+// { dg-do compile }
+// { dg-options "-fsanitize=undefined" }
+// { dg-skip-if "" { *-*-* } { "-flto" } { "" } }
+
+class A {
+ void bar (void (A::*) (int));
+ void foo (int);
+ void B ();
+};
+
+void A::B()
+{
+ bar (&A::foo);
+}
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-fsanitize=vla-bound -Wall -Wno-unused-variable" } */
+
+void foo(int i)
+{
+ /* Don't warn here with "value computed is not used". */
+ char a[i];
+}
--- /dev/null
+// { dg-do run }
+// { dg-options "-fsanitize=return" }
+// { dg-shouldfail "ubsan" }
+
+struct S { S (); ~S (); };
+
+S::S () {}
+S::~S () {}
+
+int
+foo (int x)
+{
+ S a;
+ {
+ S b;
+ if (x)
+ return 1;
+ }
+}
+
+int
+main ()
+{
+ foo (0);
+}
+
+// { dg-output "execution reached the end of a value-returning function without returning a value" }
--- /dev/null
+// { dg-do run }
+// { dg-options "-fsanitize=return" }
+
+struct S { S (); ~S (); };
+
+S::S () {}
+S::~S () {}
+
+int
+foo (int x)
+{
+ S a;
+ {
+ S b;
+ if (x)
+ return 1;
+ }
+}
+
+int
+main ()
+{
+ foo (1);
+ foo (14);
+}
template<class T>
void
-List_DL<T>::insert(const T& item, Pix x, bool before = TRUE)
+List_DL<T>::insert(const T& item, Pix x, bool before = TRUE) // { dg-error "default arguments" }
{
link<T> *l = (link<T> *) x;
--- /dev/null
+
+int a, b, d;
+short c;
+
+int
+foo ()
+{
+ for (b = 0; b; b = a)
+ for (c = 18; c < 10; c++)
+ {
+ d = c;
+ if (d)
+ return 0;
+ }
+ return 0;
+}
--- /dev/null
+/* PR tree-optimization/59362 */
+
+char *
+foo (char *r, int s)
+{
+ r = __builtin___stpcpy_chk (r, "abc", __builtin_object_size (r, 1));
+ if (s)
+ r = __builtin___stpcpy_chk (r, "d", __builtin_object_size (r, 1));
+ return r;
+}
+
+char *a;
+long int b;
+
+void
+bar (void)
+{
+ b = __builtin_object_size (0, 0);
+ a = __builtin___stpcpy_chk (0, "", b);
+ b = __builtin_object_size (a, 0);
+}
--- /dev/null
+/* PR middle-end/59138 */
+/* Testcase by John Regehr <regehr@cs.utah.edu> */
+
+extern void abort (void);
+
+#pragma pack(1)
+
+struct S0 {
+ int f0;
+ int f1;
+ int f2;
+ short f3;
+};
+
+short a = 1;
+
+struct S0 b = { 1 }, c, d, e;
+
+struct S0 fn1() { return c; }
+
+void fn2 (void)
+{
+ b = fn1 ();
+ a = 0;
+ d = e;
+}
+
+int main (void)
+{
+ fn2 ();
+ if (a != 0)
+ abort ();
+ return 0;
+}
--- /dev/null
+/* PR tree-optimization/59014 */
+
+__attribute__((noinline, noclone)) long long int
+foo (long long int x, long long int y)
+{
+ if (((int) x | (int) y) != 0)
+ return 6;
+ return x + y;
+}
+
+int
+main ()
+{
+ if (sizeof (long long) == sizeof (int))
+ return 0;
+ int shift_half = sizeof (int) * __CHAR_BIT__ / 2;
+ long long int x = (3LL << shift_half) << shift_half;
+ long long int y = (5LL << shift_half) << shift_half;
+ long long int z = foo (x, y);
+ if (z != ((8LL << shift_half) << shift_half))
+ __builtin_abort ();
+ return 0;
+}
--- /dev/null
+/* PR tree-optimization/59014 */
+
+int a = 2, b, c, d;
+
+int
+foo ()
+{
+ for (;; c++)
+ if ((b > 0) | (a & 1))
+ ;
+ else
+ {
+ d = a;
+ return 0;
+ }
+}
+
+int
+main ()
+{
+ foo ();
+ if (d != 2)
+ __builtin_abort ();
+ return 0;
+}
--- /dev/null
+int i;
+
+__attribute__((noinline, noclone)) void
+bar (char *p)
+{
+ if (i < 1 || i > 6)
+ __builtin_abort ();
+ if (__builtin_memcmp (p, "abcdefg", i + 1) != 0)
+ __builtin_abort ();
+ __builtin_memset (p, ' ', 7);
+}
+
+__attribute__((noinline, noclone)) void
+foo (char *p, unsigned long l)
+{
+ if (l < 1 || l > 6)
+ return;
+ char buf[7];
+ __builtin_memcpy (buf, p, l + 1);
+ bar (buf);
+}
+
+int
+main ()
+{
+ for (i = 0; i < 16; i++)
+ foo ("abcdefghijklmnop", i);
+ return 0;
+}
--- /dev/null
+/* PR tree-optimization/59358 */
+
+__attribute__((noinline, noclone)) int
+foo (int *x, int y)
+{
+ int z = *x;
+ if (y > z && y <= 16)
+ while (y > z)
+ z *= 2;
+ return z;
+}
+
+int
+main ()
+{
+ int i;
+ for (i = 1; i < 17; i++)
+ {
+ int j = foo (&i, 16);
+ int k;
+ if (i >= 8 && i <= 15)
+ k = 16 + (i - 8) * 2;
+ else if (i >= 4 && i <= 7)
+ k = 16 + (i - 4) * 4;
+ else if (i == 3)
+ k = 24;
+ else
+ k = 16;
+ if (j != k)
+ __builtin_abort ();
+ j = foo (&i, 7);
+ if (i >= 7)
+ k = i;
+ else if (i >= 4)
+ k = 8 + (i - 4) * 2;
+ else if (i == 3)
+ k = 12;
+ else
+ k = 8;
+ if (j != k)
+ __builtin_abort ();
+ }
+ return 0;
+}
/* No pic register. */
#elif defined(__moxie__)
/* No pic register. */
+#elif defined(__nds32__)
+/* No pic register. */
#elif defined(__hppa__)
/* PIC register is %r27 or %r19, but is used even without -fpic. */
#elif defined(__pdp11__)
/* { dg-do compile } */
-/* { dg-options "-flto" { target lto } } */
+/* { dg-options "-flto -ffat-lto-objects" { target lto } } */
typedef struct foo_ foo_t;
foo_t bar; /* { dg-error "storage size of 'bar' isn't known" } */
/* { dg-do run } */
-/* { dg-skip-if "Variadic funcs have all args on stack. Normal funcs have args in registers." { "aarch64*-*-* avr-*-* " } { "*" } { "" } } */
+/* { dg-skip-if "Variadic funcs have all args on stack. Normal funcs have args in registers." { "aarch64*-*-* avr-*-* nds32*-*-*" } { "*" } { "" } } */
/* { dg-skip-if "Variadic funcs use Base AAPCS. Normal funcs use VFP variant." { arm*-*-* && arm_hf_eabi } { "*" } { "" } } */
/* PR target/12503 */
--- /dev/null
+/* Test for non-lvalue arrays: test that they cannot be assigned to
+ array variables. PR 58235. */
+/* { dg-do compile } */
+/* { dg-options "-std=iso9899:1990 -pedantic-errors" } */
+
+struct s { char c[1]; } x;
+struct s f (void) { return x; }
+
+void
+g (void)
+{
+ char c[1];
+ c = f ().c; /* { dg-error "array" } */
+}
+
+void
+h (void)
+{
+ char c[1] = f ().c; /* { dg-error "array" } */
+}
/* { dg-error "3:overflow in constant expression" "constant" { target *-*-* } 22 } */
E6 = 0 * !-INT_MIN, /* { dg-warning "13:integer overflow in expression" } */
/* { dg-error "8:not an integer constant" "constant" { target *-*-* } 24 } */
- E7 = INT_MIN % -1 /* Not an overflow. */
+ E7 = INT_MIN % -1 /* { dg-warning "16:integer overflow in expression" } */
+ /* { dg-error "1:overflow in constant expression" "constant" { target *-*-* } 28 } */
};
/* { dg-error "overflow in constant expression" "constant" { target *-*-* } 22 } */
E6 = 0 * !-INT_MIN, /* { dg-warning "integer overflow in expression" } */
/* { dg-error "not an integer constant" "constant" { target *-*-* } 24 } */
- E7 = INT_MIN % -1 /* Not an overflow. */
+ E7 = INT_MIN % -1 /* { dg-warning "16:integer overflow in expression" } */
+ /* { dg-error "1:overflow in constant expression" "constant" { target *-*-* } 28 } */
};
--- /dev/null
+/* Test for designated initializers: string constants used with
+ designator in character array should not initialize the array as a
+ whole. */
+/* { dg-do compile } */
+/* { dg-options "-std=iso9899:1999 -pedantic-errors" } */
+
+char g[] = { [7] = "abcd" }; /* { dg-error "initial" } */
+char h[10][10] = { [1][1] = "abcd" }; /* { dg-error "initial" } */
+char i[10][10] = { [1] = "abcd" };
--- /dev/null
+/* Test for designated initializers: invalid uses of string constants
+ should not ICE. PR 42262. */
+/* { dg-do compile } */
+/* { dg-options "-std=iso9899:1999 -pedantic-errors" } */
+
+int a[] = { [0 ... 1] = "", [0] = "" }; /* { dg-error "initial" } */
set library_var [get_multilibs]
# Pointing the ld_library_path to the Cilk Runtime library binaries.
-set ld_library_path "${library_var}/libcilkrts/.libs"
+append ld_library_path ":${library_var}/libcilkrts/.libs"
+set_ld_library_path_env_vars
global TEST_EXTRA_LIBS
set TEST_EXTRA_LIBS "-L${library_var}/libcilkrts/.libs"
floating-point contents expressed in decimal. PR 21718. */
/* { dg-do run } */
/* { dg-options "-w" } */
+/* { dg-add-options ieee } */
/* For float (if IEEE binary32), double (if IEEE binary64) and long
double (if IEEE binary64, x86 extended or IEEE binary128) we test
182358152808745703724362178773168996492870519432472065091133\
11767578125001e-4966L;
/* 0x1.8p-16494 */
-static const long double ld2ae = 0x1p-16494L, ld2be = 0x2p-16494L, ld1ce = 0x2p-16494L;
+static const long double ld2ae = 0x1p-16494L, ld2be = 0x2p-16494L, ld2ce = 0x2p-16494L;
static const long double ld2a =
9.7127626791570376663866584373414698287493540070520215145348\
265837955593101861790565265072369149749103838172122152721795\
/* { dg-final { scan-tree-dump-not "omp teams" "original" } } */
/* { dg-final { scan-tree-dump-not "omp target" "original" } } */
/* { dg-final { scan-tree-dump-not "omp parallel" "original" } } */
+/* { dg-final { cleanup-tree-dump "original" } } */
/* { dg-final { scan-tree-dump-times "pragma omp simd safelen\\(64\\)" 1 "original" } } */
/* { dg-final { scan-tree-dump-not "omp parallel" "original" } } */
/* { dg-final { scan-tree-dump-not "omp for" "original" } } */
+/* { dg-final { cleanup-tree-dump "original" } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-fopenmp -fdump-tree-optimized -O3" } */
+
+/* Test that functions that have SIMD clone counterparts are not
+ cloned by IPA-cp. For example, special_add() below has SIMD clones
+ created for it. However, if IPA-cp later decides to clone a
+ specialization of special_add(x, 666) when analyzing fillit(), we
+ will forever keep the vectorizer from using the SIMD versions of
+ special_add in a loop.
+
+ If IPA-CP gets taught how to adjust the SIMD clones as well, this
+ test could be removed. */
+
+#pragma omp declare simd simdlen(4)
+static int __attribute__ ((noinline))
+special_add (int x, int y)
+{
+ if (y == 666)
+ return x + y + 123;
+ else
+ return x + y;
+}
+
+void fillit(int *tot)
+{
+ int i;
+
+ for (i=0; i < 10000; ++i)
+ tot[i] = special_add (i, 666);
+}
+
+/* { dg-final { scan-tree-dump-not "special_add.constprop" "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
--- /dev/null
+/* { dg-options "-fopenmp -fdump-tree-optimized -O" } */
+
+#pragma omp declare simd inbranch uniform(c) linear(b:66)
+#pragma omp declare simd notinbranch aligned(c:32)
+int addit(int a, int b, int *c)
+{
+ return a + b;
+}
+
+#pragma omp declare simd uniform(a) aligned(a:32) linear(k:1) notinbranch
+float setArray(float *a, float x, int k)
+{
+ a[k] = a[k] + x;
+ return a[k];
+}
+
+/* { dg-final { scan-tree-dump "_ZGVbN4ua32vl_setArray" "optimized" { target i?86-*-* x86_64-*-* } } } */
+/* { dg-final { scan-tree-dump "_ZGVbN4vvva32_addit" "optimized" { target i?86-*-* x86_64-*-* } } } */
+/* { dg-final { scan-tree-dump "_ZGVbM4vl66u_addit" "optimized" { target i?86-*-* x86_64-*-* } } } */
+/* { dg-final { scan-tree-dump "_ZGVcN8ua32vl_setArray" "optimized" { target i?86-*-* x86_64-*-* } } } */
+/* { dg-final { scan-tree-dump "_ZGVcN4vvva32_addit" "optimized" { target i?86-*-* x86_64-*-* } } } */
+/* { dg-final { scan-tree-dump "_ZGVcM4vl66u_addit" "optimized" { target i?86-*-* x86_64-*-* } } } */
+/* { dg-final { scan-tree-dump "_ZGVdN8ua32vl_setArray" "optimized" { target i?86-*-* x86_64-*-* } } } */
+/* { dg-final { scan-tree-dump "_ZGVdN8vvva32_addit" "optimized" { target i?86-*-* x86_64-*-* } } } */
+/* { dg-final { scan-tree-dump "_ZGVdM8vl66u_addit" "optimized" { target i?86-*-* x86_64-*-* } } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
--- /dev/null
+/* { dg-options "-fopenmp -fdump-tree-optimized -O2" } */
+
+/* Test that if there is no *inbranch clauses, that both the masked and
+ the unmasked version are created. */
+
+#pragma omp declare simd
+int addit(int a, int b, int c)
+{
+ return a + b;
+}
+
+/* { dg-final { scan-tree-dump "_ZGVbN4vvv_addit" "optimized" { target i?86-*-* x86_64-*-* } } } */
+/* { dg-final { scan-tree-dump "_ZGVbM4vvv_addit" "optimized" { target i?86-*-* x86_64-*-* } } } */
+/* { dg-final { scan-tree-dump "_ZGVcN4vvv_addit" "optimized" { target i?86-*-* x86_64-*-* } } } */
+/* { dg-final { scan-tree-dump "_ZGVcM4vvv_addit" "optimized" { target i?86-*-* x86_64-*-* } } } */
+/* { dg-final { scan-tree-dump "_ZGVdN8vvv_addit" "optimized" { target i?86-*-* x86_64-*-* } } } */
+/* { dg-final { scan-tree-dump "_ZGVdM8vvv_addit" "optimized" { target i?86-*-* x86_64-*-* } } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
--- /dev/null
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-fopenmp" } */
+
+#pragma omp declare simd simdlen(4) notinbranch
+int f2 (int a, int b)
+{
+ if (a > 5)
+ return a + b;
+ else
+ return a - b;
+}
--- /dev/null
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-fopenmp -w" } */
+
+/* ?? The -w above is to inhibit the following warning for now:
+ a.c:2:6: warning: AVX vector argument without AVX enabled changes
+ the ABI [enabled by default]. */
+
+#pragma omp declare simd notinbranch simdlen(4)
+void foo (int *a)
+{
+ *a = 555;
+}
--- /dev/null
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-fopenmp" } */
+
+/* Test that array subscripts are properly adjusted. */
+
+int array[1000];
+#pragma omp declare simd notinbranch simdlen(4)
+void foo (int i)
+{
+ array[i] = 555;
+}
--- /dev/null
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-fopenmp -w" } */
+
+int array[1000];
+
+#pragma omp declare simd notinbranch simdlen(4)
+void foo (int *a, int b)
+{
+ a[b] = 555;
+}
+
+#pragma omp declare simd notinbranch simdlen(4)
+void bar (int *a)
+{
+ *a = 555;
+}
--- /dev/null
+/* { dg-do run } */
+/* { dg-options "-g" } */
+/* { dg-skip-if "" { *-*-* } { "*" } { "-O0" "-O1" } } */
+
+typedef __UINTPTR_TYPE__ uintptr_t;
+
+__attribute__((noinline, noclone)) int
+sub (int a, int b)
+{
+ return a - b;
+}
+
+typedef struct { uintptr_t pa; uintptr_t pb; } fatp_t
+ __attribute__ ((aligned (2 * __alignof__ (uintptr_t))));
+
+__attribute__((noinline, noclone)) void
+foo (fatp_t str, int a, int b)
+{
+ int i = sub (a, b);
+ if (i == 0) /* BREAK */
+ foo (str, a - 1, b);
+}
+
+int
+main (void)
+{
+ fatp_t ptr = { 31415927, 27182818 };
+ foo (ptr, 1, 2);
+ return 0;
+}
+
+/* { dg-final { gdb-test 20 "str.pa" "31415927" } } */
+/* { dg-final { gdb-test 20 "str.pb" "27182818" } } */
--- /dev/null
+/* A function definition of an inline function following a static
+ declaration does not make an inline definition in C99/C11 terms.
+ PR 57574. */
+/* { dg-do compile } */
+/* { dg-options "-std=c99 -pedantic-errors" } */
+
+static int n;
+
+static inline int f1 (void);
+inline int f1 (void) { return n; }
+
+static int f2 (void);
+inline int f2 (void) { return n; }
+
+static inline int f3 (void);
+int f3 (void) { return n; }
+
+static int f4 (void);
+int f4 (void) { return n; }
-/* { dg-do compile { target { x86_64-*-* && lp64 } } } */
+/* { dg-do compile { target { { x86_64-*-* && lp64 } || { powerpc*-*-* && lp64 } } } } */
/* { dg-options "-O3 -fdump-rtl-ira -fdump-rtl-pro_and_epilogue" } */
-int __attribute__((noinline, noclone))
-foo (int a)
+long __attribute__((noinline, noclone))
+foo (long a)
{
return a + 5;
}
-static int g;
+static long g;
-int __attribute__((noinline, noclone))
-bar (int a)
+long __attribute__((noinline, noclone))
+bar (long a)
{
- int r;
+ long r;
if (a)
{
-/* { dg-do compile { target { x86_64-*-* && lp64 } } } */
+/* { dg-do compile { target { { x86_64-*-* && lp64 } || { powerpc*-*-* && lp64 } } } } */
/* { dg-options "-O3 -fdump-rtl-ira -fdump-rtl-pro_and_epilogue" } */
-int __attribute__((noinline, noclone))
-foo (int a)
+long __attribute__((noinline, noclone))
+foo (long a)
{
return a + 5;
}
-static int g;
+static long g;
-int __attribute__((noinline, noclone))
-bar (int a)
+long __attribute__((noinline, noclone))
+bar (long a)
{
- int r;
+ long r;
if (a)
{
--- /dev/null
+/* { dg-lto-do link } */
+/* { dg-lto-options { { -O2 -g -flto } } } */
+/* { dg-extra-ld-options { -r -nostdlib } } */
+
+extern void bar(void);
+
+int main(int argc, char **argv)
+{
+ int i;
+
+ if (argc == 1) {
+ extern void bar ();
+
+ bar();
+
+ {
+ extern void bar ();
+
+ asm goto ("" : : : : lab);
+lab:
+ ;
+ }
+ }
+
+ {
+ extern void bar ();
+
+ int foo(void)
+ {
+ return argv[0][0];
+ }
+
+ i = foo();
+ }
+
+ return i;
+}
--- /dev/null
+/* { dg-lto-do link } */
+/* { dg-lto-options { { -O2 -g -flto } } } */
+/* { dg-extra-ld-options { -r -nostdlib } } */
+
+extern void bar(void);
+
+int main(int argc, char **argv)
+{
+ int i;
+
+ if (argc == 1) {
+ enum { X };
+
+ bar();
+
+ {
+ enum { X };
+
+ asm goto ("" : : : : lab);
+lab:
+ ;
+ }
+ }
+
+ {
+ enum { X };
+
+ int foo(void)
+ {
+ return argv[0][0];
+ }
+
+ i = foo();
+ }
+
+ return i;
+}
--- /dev/null
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -mtune=corei7 -fdump-rtl-sched2" } */
+/* { dg-final { scan-rtl-dump-not "compare.*insn.*jump_insn.*jump_insn" "sched2" } } */
+
+int a[100];
+
+double bar (double sum)
+{
+ int i;
+ for (i = 0; i < 1000000; i++)
+ sum += (0.5 + (a[i%100] - 128));
+ return sum;
+}
--- /dev/null
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -mtune=corei7-avx -fdump-rtl-sched2" } */
+/* { dg-final { scan-rtl-dump-not "compare.*insn.*jump_insn.*jump_insn" "sched2" } } */
+
+int a[100];
+
+double bar (double sum)
+{
+ int i = 100000;
+ while (i != 0)
+ {
+ sum += (0.5 + (a[i%100] - 128));
+ i--;
+ }
+ return sum;
+}
#include "tree.h"
#include "toplev.h"
#include "basic-block.h"
+#include "pointer-set.h"
+#include "hash-table.h"
+#include "vec.h"
+#include "ggc.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-fold.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "tree.h"
#include "tree-pass.h"
#include "tree.h"
#include "toplev.h"
#include "basic-block.h"
+#include "pointer-set.h"
+#include "hash-table.h"
+#include "vec.h"
+#include "ggc.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-fold.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "tree.h"
#include "tree-pass.h"
#include "tree.h"
#include "tm.h"
#include "toplev.h"
+#include "pointer-set.h"
+#include "hash-table.h"
+#include "vec.h"
+#include "ggc.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-fold.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "tree-pass.h"
#include "intl.h"
#include "stringpool.h"
#include "toplev.h"
#include "basic-block.h"
+#include "pointer-set.h"
+#include "hash-table.h"
+#include "vec.h"
+#include "ggc.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-fold.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "tree.h"
#include "stringpool.h"
#include "toplev.h"
#include "basic-block.h"
+#include "pointer-set.h"
+#include "hash-table.h"
+#include "vec.h"
+#include "ggc.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-fold.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "tree.h"
#include "tree-pass.h"
-/* { dg-do compile { target { x86_64-*-* && lp64 } } } */
+/* { dg-do compile { target { { x86_64-*-* && lp64 } || { powerpc*-*-* && lp64 } } } } */
/* { dg-options "-O3 -fdump-rtl-pro_and_epilogue" } */
void f(int *i)
--- /dev/null
+/* Test volatile access to unaligned field. */
+/* { dg-do compile } */
+/* { dg-options "-fno-strict-volatile-bitfields -fdump-rtl-final" } */
+
+#define test_type unsigned short
+
+typedef struct s{
+ unsigned char Prefix[1];
+ volatile test_type Type;
+}__attribute((__packed__,__aligned__(4))) ss;
+
+extern volatile ss v;
+
+void
+foo (test_type u)
+{
+ v.Type = u;
+}
+
+/* The C++ memory model forbids data store race conditions outside the
+ unaligned data member, therefore only QI or HI access is allowed, no SI. */
+/* { dg-final { scan-rtl-dump-not "mem/v(/.)*:SI" "final" } } */
+/* { dg-final { cleanup-rtl-dump "final" } } */
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-rtl-ira" } */
-/* { dg-final { scan-rtl-dump-not "REG_EQUIV\[^\n\]*mem\[^\n\]*\"ip\".*subreg" "ira" } } */
char ip[10];
int total;
t = ip[2];
total = t & 0x3;
}
+
+/* { dg-final { scan-rtl-dump-not "REG_EQUIV\[^\n\]*mem\[^\n\]*\"ip\".*subreg" "ira" } } */
+/* { dg-final { cleanup-rtl-dump "ira" } } */
--- /dev/null
+/* PR middle-end/59011 */
+/* { dg-do compile } */
+/* { dg-options "-std=gnu99" } */
+
+void
+foo (int m)
+{
+ int a[m];
+ void
+ bar (void)
+ {
+ {
+ int
+ baz (void)
+ {
+ return a[0];
+ }
+ }
+ a[0] = 42;
+ }
+ bar ();
+}
--- /dev/null
+/* PR rtl-optimization/59020 */
+
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -fmodulo-sched -fno-inline -march=corei7" } */
+
+int a, b, d;
+unsigned c;
+
+void f()
+{
+ unsigned q;
+ for(; a; a++)
+ if(((c %= d && 1) ? : 1) & 1)
+ for(; b; q++);
+}
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-std=c99 -Wpedantic" } */
+
+unsigned int
+foo (void)
+{
+ return sizeof ((int[]) {}); /* { dg-warning "ISO C forbids empty initializer braces" } */
+}
Copyright (C) 2002 Free Software Foundation Inc.
Contributed by Hans-Peter Nilsson <hp@bitrange.com> */
-/* { dg-do run { xfail { { cris-*-* crisv32-*-* h8300-*-* hppa*64*-*-* m32r-*-* mcore-*-* mn10300-*-* xstormy16-*-* v850*-*-* vax-*-* xtensa*-*-* } || { arm*-*-* && { ! arm32 } } } } } */
+/* { dg-do run { xfail { { cris-*-* crisv32-*-* h8300-*-* hppa*64*-*-* m32r-*-* mcore-*-* mn10300-*-* nds32*-*-* xstormy16-*-* v850*-*-* vax-*-* xtensa*-*-* } || { arm*-*-* && { ! arm32 } } } } } */
/* -mlongcall disables sibcall patterns. */
/* { dg-skip-if "" { powerpc*-*-* } { "-mlongcall" } { "" } } */
/* { dg-options "-O2 -foptimize-sibling-calls" } */
Copyright (C) 2002 Free Software Foundation Inc.
Contributed by Hans-Peter Nilsson <hp@bitrange.com> */
-/* { dg-do run { xfail { { cris-*-* crisv32-*-* h8300-*-* hppa*64*-*-* m32r-*-* mcore-*-* mn10300-*-* xstormy16-*-* v850*-*-* vax-*-* xtensa*-*-* } || { arm*-*-* && { ! arm32 } } } } } */
+/* { dg-do run { xfail { { cris-*-* crisv32-*-* h8300-*-* hppa*64*-*-* m32r-*-* mcore-*-* mn10300-*-* nds32*-*-* xstormy16-*-* v850*-*-* vax-*-* xtensa*-*-* } || { arm*-*-* && { ! arm32 } } } } } */
/* -mlongcall disables sibcall patterns. */
/* { dg-skip-if "" { powerpc*-*-* } { "-mlongcall" } { "" } } */
/* { dg-options "-O2 -foptimize-sibling-calls" } */
# else
# define SIZE 248
# endif
+#elif defined (__nds32__)
+# define SIZE 248 /* 256 - 8 bytes, only $fp and padding bytes are saved in
+ the register save area under O0 optimization level. */
#elif defined (__powerpc64__) || defined (__ppc64__) || defined (__POWERPC64__) \
|| defined (__PPC64__)
# if _CALL_ELF == 2
/* { dg-do run } */
/* { dg-options "-fno-strict-aliasing" } */
-/* { dg-skip-if "unaligned access" { arc*-*-* epiphany-*-* sparc*-*-* sh*-*-* tic6x-*-* } "*" "" } */
+/* { dg-skip-if "unaligned access" { arc*-*-* epiphany-*-* nds32*-*-* sparc*-*-* sh*-*-* tic6x-*-* } "*" "" } */
extern void abort (void);
#if (__SIZEOF_INT__ <= 2)
--- /dev/null
+/* PR middle-end/57393 */
+/* { dg-do compile } */
+/* { dg-additional-options "-g -ffast-math" } */
+
+extern void bar (double);
+
+struct S { int n; };
+
+void
+foo (struct S s, double a, int i, int j, int k)
+{
+ struct S t;
+ bar (s.n * a * i * j);
+ t.n = s.n * a * i * k;
+}
--- /dev/null
+/* PR middle-end/57393 */
+/* { dg-do compile } */
+
+char a;
+
+foo (int **p)
+{
+ int b;
+ for (;;)
+ {
+ int c[1] = { 0 };
+ unsigned *d = &c[0];
+ for (b = 7; b; b--)
+ **p &= --*d >= a;
+ }
+}
--- /dev/null
+/* PR middle-end/57393 */
+/* { dg-do compile } */
+
+int a, b, c;
+void foo (void);
+
+int
+bar (void)
+{
+ for (;;)
+ {
+ foo ();
+ int d = a = 0;
+ for (; a < 7; ++a)
+ {
+ d--;
+ b &= c <= d;
+ }
+ }
+}
--- /dev/null
+/* PR tree-optimization/58018 */
+/* { dg-do compile } */
+
+int a, b, c, d, e;
+
+void
+bar (int p)
+{
+ int f = b;
+ e &= p <= (f ^= 0);
+}
+
+void
+foo ()
+{
+ for (; d; d++)
+ {
+ bar (a && c);
+ bar (0);
+ bar (1);
+ }
+}
--- /dev/null
+/* PR tree-optimization/58131 */
+/* { dg-do compile } */
+
+short a;
+int b, c, d[1][4][2];
+
+void
+foo (void)
+{
+ int *e;
+ for (b = 1; ; b--)
+ {
+ if (*e)
+ break;
+ for (c = 2; c >= 0; c--)
+ {
+ *e |= d[0][3][b] != a;
+ int *f = &d[0][3][b];
+ *f = 0;
+ }
+ }
+}
--- /dev/null
+/* { dg-do compile } */
+
+int a, b, c, d, e;
+int fn1(p1, p2) { return p2 == 0 ? p1 : 1 % p2; }
+
+void fn2()
+{
+ c = 0;
+ for (;; c = (unsigned short)c)
+ {
+ b = 2;
+ for (; b; b = a)
+ {
+ e = fn1(2, c && 1);
+ d = c == 0 ? e : c;
+ if (d)
+ return;
+ }
+ }
+}
--- /dev/null
+/* PR rtl-optimization/59166 */
+/* { dg-additional-options "-fcompare-debug" } */
+
+int a, b, c, f, g;
+
+void
+foo ()
+{
+ for (; b; b++)
+ for (; f; f = g)
+ for (; a;)
+ ;
+}
+
+static int
+bar (int p)
+{
+ short d;
+ if (c)
+ {
+ for (; f; f = g);
+ foo ();
+ d = p;
+ char e = d;
+ if (p)
+ return 1;
+ }
+ return p;
+}
+
+int
+main ()
+{
+ bar (0);
+ bar (g);
+ return 0;
+}
--- /dev/null
+/* { dg-do run } */
+
+#include <limits.h>
+
+extern void abort (void);
+extern void exit (int);
+
+long long __attribute__((noinline)) f(int a)
+{
+ return -(long long) a;
+}
+
+int
+main()
+{
+ if (f(0) != 0)
+ abort ();
+
+ if (f(1) != -(long long)1)
+ abort ();
+
+ if (f(-1) != -(long long)-1)
+ abort ();
+
+ if (f(INT_MIN) != -(long long)INT_MIN)
+ abort ();
+
+ if (f(INT_MAX) != -(long long)INT_MAX)
+ abort ();
+
+ exit (0);
+}
--- /dev/null
+/* { dg-do compile } */
+
+int a, b, c, e, g;
+char d[5], f;
+
+int
+fn1 ()
+{
+ if (b)
+ {
+ g = 0;
+ return 0;
+ }
+ for (f = 0; f != 1; f--)
+ ;
+ return 0;
+}
+
+void
+fn2 ()
+{
+ d[4] = -1;
+ for (a = 4; a; a--)
+ {
+ fn1 ();
+ e = c < -2147483647 - 1 - d[a] ? c : 0;
+ }
+}
--- /dev/null
+/* { dg-do compile } */
+
+void
+baz (int *d)
+{
+ long int i, j, k;
+ for (i = 0, j = 0, k = 0; i < 512; i = (int) i + 1, j = (int) j + 1, k = (int) k + 3)
+ d[i] = j ^ (i * 3) ^ (2 * k + 2);
+}
--- /dev/null
+/* { dg-do run } */
+
+void free(void *ptr)
+{
+}
+
+void *foo(void)
+{
+ return 0;
+}
+
+int main(void)
+{
+ void *p = foo();
+ free(p);
+ return 0;
+}
--- /dev/null
+/* { dg-do compile } */
+
+typedef enum
+{
+ XYZZY,
+} enumType;
+
+typedef struct
+{
+ unsigned char More : 1;
+} tResp;
+
+typedef struct
+{
+ enumType QueryType;
+ union
+ {
+ tResp l[0];
+ } u;
+} tQResp;
+
+void test(void)
+{
+ tQResp *qResp = (0);
+ if (qResp->u.l[0].More == 0)
+ return;
+}
avr: Variadic funcs don't pass arguments in registers, while normal funcs
do. */
/* { dg-skip-if "Variadic funcs use different argument passing from normal funcs" { arm_hf_eabi || { avr-*-* } } "*" "" } */
+/* { dg-skip-if "Variadic funcs have all args on stack. Normal funcs have args in registers." { nds32*-*-* } "*" "" } */
#define INTEGER_ARG 5
/* Test case to check if function foo gets split and the cold function
gets a label. */
/* { dg-require-effective-target freorder } */
-/* { dg-options "-O2 -freorder-blocks-and-partition --save-temps" } */
+/* { dg-options "-O2 -freorder-blocks-and-partition -save-temps" } */
#define SIZE 10000
foo (argc);
return 0;
}
+
+/* { dg-final-use { cleanup-saved-temps } } */
that the && should be emitted (based on BRANCH_COST). Fix this
by teaching dom to look through && and register all components
as true. */
-/* { dg-final { scan-tree-dump-times "link_error" 0 "optimized" { xfail { ! "alpha*-*-* arm*-*-* powerpc*-*-* cris-*-* crisv32-*-* hppa*-*-* i?86-*-* mmix-*-* mips*-*-* m68k*-*-* moxie-*-* sparc*-*-* spu-*-* x86_64-*-*" } } } } */
+/* { dg-final { scan-tree-dump-times "link_error" 0 "optimized" { xfail { ! "alpha*-*-* arm*-*-* powerpc*-*-* cris-*-* crisv32-*-* hppa*-*-* i?86-*-* mmix-*-* mips*-*-* m68k*-*-* moxie-*-* nds32*-*-* sparc*-*-* spu-*-* x86_64-*-*" } } } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-optimized" } */
+
+union X {
+ int i;
+ void *p;
+};
+void bar (int);
+
+int * __attribute__((noinline,noclone))
+baz (int *p) { return p; }
+
+void foo (union X *x)
+{
+ struct Y { int i; } ystruct = {};
+ ystruct.i = * baz (&ystruct.i);
+ bar (x->i);
+}
+
+/* DSE and then DCE should be able to remove all uses of ystruct.
+ Formerly the union access for the parameter to bar let 'anything'
+ escape which made the call to bar possibly use ystruct and thus
+ prevent the store to ystruct.i from being eliminated. The call to
+ baz makes sure that ystruct has its address taken. */
+
+/* { dg-final { scan-tree-dump-not "ystruct" "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
return b+a;
}
/* { dg-final { scan-tree-dump "return 8" "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
-
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-isolate-paths -fdump-tree-optimized" } */
-
struct demangle_component
{
};
-
struct d_info
{
struct demangle_component *comps;
int num_comps;
};
-
static struct demangle_component *
d_make_empty (struct d_info *di)
{
return p;
}
-
-
struct demangle_component *
d_type (struct d_info *di)
{
/* { dg-final { scan-tree-dump-times "\\.type" 1 "optimized"} } */
/* { dg-final { scan-tree-dump-times "->zzz" 1 "isolate-paths"} } */
/* { dg-final { cleanup-tree-dump "isolate-paths" } } */
-/* { dg-final { cleanup-tree-dump "optimized-paths" } } */
-
-
-
-
+/* { dg-final { cleanup-tree-dump "optimized" } } */
/* Whether the structs are totally scalarized or not depends on the
MOVE_RATIO macro definition in the back end. The scalarization will
not take place when using small values for MOVE_RATIO. */
-/* { dg-final { scan-tree-dump-times "struct _fat_ptr _ans" 0 "optimized" { target { ! "arm*-*-* avr-*-* powerpc*-*-* s390*-*-* sh*-*-*" } } } } */
-/* { dg-final { scan-tree-dump-times "struct _fat_ptr _T2" 0 "optimized" { target { ! "arm*-*-* avr-*-* powerpc*-*-* s390*-*-* sh*-*-*" } } } } */
+/* { dg-final { scan-tree-dump-times "struct _fat_ptr _ans" 0 "optimized" { target { ! "arm*-*-* avr-*-* nds32*-*-* powerpc*-*-* s390*-*-* sh*-*-*" } } } } */
+/* { dg-final { scan-tree-dump-times "struct _fat_ptr _T2" 0 "optimized" { target { ! "arm*-*-* avr-*-* nds32*-*-* powerpc*-*-* s390*-*-* sh*-*-*" } } } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */
}
/* { dg-final { scan-tree-dump "Deleted dead store" "dse1"} } */
+/* { dg-final { cleanup-tree-dump "dse1" } } */
*PINDEX: C1 + (C2 * C3) + C4 */
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-slsr" } */
+/* { dg-options "-O2 -fdump-tree-slsr-details" } */
typedef int arr_2[50][50];
return;
}
-/* { dg-final { scan-tree-dump-times "MEM" 4 "slsr" } } */
+/* { dg-final { scan-tree-dump-times "Replacing reference: " 4 "slsr" } } */
/* { dg-final { cleanup-tree-dump "slsr" } } */
--- /dev/null
+/* Verify straight-line strength reduction in using
+ alternative base expr to record and look for the
+ potential candidate. */
+
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-slsr-details" } */
+
+typedef int arr_2[50][50];
+
+void foo (arr_2 a2, int v1)
+{
+ int i, j;
+
+ i = v1 + 5;
+ j = i;
+ a2 [i-10] [j] = 2;
+ a2 [i] [j++] = i;
+ a2 [i+20] [j++] = i;
+ a2 [i-3] [i-1] += 1;
+ return;
+}
+
+/* { dg-final { scan-tree-dump-times "Replacing reference: " 5 "slsr" } } */
+/* { dg-final { cleanup-tree-dump "slsr" } } */
*p = l;
}
-/* { dg-final { scan-tree-dump-times "l;" 0 "release_ssa" { target { ! "avr*-*-*" } } } } */
+/* { dg-final { scan-tree-dump-times "l;" 0 "release_ssa" { target { ! "avr*-*-* nds32*-*-*" } } } } */
/* { dg-final { cleanup-tree-dump "release_ssa" } } */
/* { dg-require-effective-target vect_int } */
+/* { dg-skip-if "cost too high" { powerpc*le-*-* } { "*" } { "" } } */
#include <stdarg.h>
#include "../../tree-vect.h"
abort ();
return 0;
}
+
+/* { dg-final { cleanup-tree-dump "vect" } } */
--- /dev/null
+/* { dg-require-effective-target vect_simd_clones } */
+/* { dg-additional-options "-fopenmp-simd" } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+
+#include "tree-vect.h"
+
+#ifndef N
+#define N 1024
+#endif
+
+int array[N];
+
+#pragma omp declare simd simdlen(4) notinbranch
+#pragma omp declare simd simdlen(4) notinbranch uniform(b) linear(c:3)
+#pragma omp declare simd simdlen(8) notinbranch
+#pragma omp declare simd simdlen(8) notinbranch uniform(b) linear(c:3)
+__attribute__((noinline)) int
+foo (int a, int b, int c)
+{
+ if (a < 30)
+ return 5;
+ return a + b + c;
+}
+
+__attribute__((noinline, noclone)) void
+bar ()
+{
+ int i;
+#pragma omp simd
+ for (i = 0; i < N; ++i)
+ array[i] = foo (i, 123, i * 3);
+}
+
+__attribute__((noinline, noclone)) void
+baz ()
+{
+ int i;
+#pragma omp simd
+ for (i = 0; i < N; ++i)
+ array[i] = foo (i, array[i], i * 3);
+}
+
+int
+main ()
+{
+ int i;
+ check_vect ();
+ bar ();
+ for (i = 0; i < N; i++)
+ if (array[i] != (i < 30 ? 5 : i * 4 + 123))
+ abort ();
+ baz ();
+ for (i = 0; i < N; i++)
+ if (array[i] != (i < 30 ? 5 : i * 8 + 123))
+ abort ();
+ return 0;
+}
+
+/* { dg-final { cleanup-tree-dump "vect" } } */
--- /dev/null
+/* { dg-require-effective-target vect_simd_clones } */
+/* { dg-additional-options "-fopenmp-simd" } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+/* { dg-additional-sources vect-simd-clone-10a.c } */
+
+#include "tree-vect.h"
+
+#ifndef N
+#define N 1024
+#endif
+
+int a[N], b[N];
+long int c[N];
+unsigned char d[N];
+
+#include "vect-simd-clone-10.h"
+
+__attribute__((noinline)) void
+fn1 (void)
+{
+ int i;
+ #pragma omp simd
+ for (i = 0; i < N; i++)
+ a[i] = foo (c[i], a[i], b[i]) + 6;
+ #pragma omp simd
+ for (i = 0; i < N; i++)
+ c[i] = bar (a[i], b[i], c[i]) * 2;
+}
+
+__attribute__((noinline)) void
+fn2 (void)
+{
+ int i;
+ #pragma omp simd
+ for (i = 0; i < N; i++)
+ {
+ a[i] = foo (c[i], a[i], b[i]) + 6;
+ d[i]++;
+ }
+ #pragma omp simd
+ for (i = 0; i < N; i++)
+ {
+ c[i] = bar (a[i], b[i], c[i]) * 2;
+ d[i] /= 2;
+ }
+}
+
+__attribute__((noinline)) void
+fn3 (void)
+{
+ int i;
+ for (i = 0; i < N; i++)
+ {
+ a[i] = i * 2;
+ b[i] = 17 + (i % 37);
+ c[i] = (i & 63);
+ d[i] = 16 + i;
+ }
+}
+
+int
+main ()
+{
+ int i;
+ check_vect ();
+ fn3 ();
+ fn1 ();
+ for (i = 0; i < N; i++)
+ if (a[i] != i * 2 + 23 + (i % 37) + (i & 63)
+ || b[i] != 17 + (i % 37)
+ || c[i] != i * 4 + 80 + 4 * (i % 37) + 4 * (i & 63))
+ abort ();
+ fn3 ();
+ fn2 ();
+ for (i = 0; i < N; i++)
+ if (a[i] != i * 2 + 23 + (i % 37) + (i & 63)
+ || b[i] != 17 + (i % 37)
+ || c[i] != i * 4 + 80 + 4 * (i % 37) + 4 * (i & 63)
+ || d[i] != ((unsigned char) (17 + i)) / 2)
+ abort ();
+ return 0;
+}
+
+/* { dg-final { cleanup-tree-dump "vect" } } */
--- /dev/null
+#pragma omp declare simd notinbranch
+extern int foo (long int a, int b, int c);
+#pragma omp declare simd notinbranch
+extern long int bar (int a, int b, long int c);
--- /dev/null
+/* { dg-do compile } */
+
+#include "vect-simd-clone-10.h"
+
+#pragma omp declare simd notinbranch
+int
+foo (long int a, int b, int c)
+{
+ return a + b + c;
+}
+
+#pragma omp declare simd notinbranch
+long int
+bar (int a, int b, long int c)
+{
+ return a + b + c;
+}
--- /dev/null
+/* { dg-require-effective-target vect_simd_clones } */
+/* { dg-additional-options "-fopenmp-simd" } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+
+#include "tree-vect.h"
+
+#ifndef N
+#define N 1024
+#endif
+
+int a[N] __attribute__((aligned (32)));
+
+#pragma omp declare simd linear(a) linear(b:3) linear(c:6) notinbranch
+__attribute__((noinline)) int
+foo (int a, int b, int c)
+{
+ return a ^ (b * 512) ^ (c * 512 * 512);
+}
+
+__attribute__((noinline, noclone)) void
+bar (int *d)
+{
+ int i, j, k;
+ for (i = 0, j = 0, k = 0; i < N / 2; i++, j++, k += 3)
+ d[i] = foo (j, i * 3, 2 * k + 2);
+}
+
+#if 0
+__attribute__((noinline, noclone)) void
+baz (int *d)
+{
+ long int i, j, k;
+ for (i = 0, j = 0, k = 0; i < N / 2;
+ i = (int) i + 1, j = (int) j + 1, k = (int) k + 3)
+ d[i] = foo (j, i * 3, 2 * k + 2);
+}
+#endif
+
+int
+main ()
+{
+ int i;
+ check_vect ();
+ if (sizeof (int) * __CHAR_BIT__ < 32)
+ return 0;
+ bar (a + 7);
+ for (i = 0; i < N / 2; i++)
+ if (a[i + 7] != (i ^ (i * 3 * 512) ^ (((i * 6) + 2) * 512 * 512)))
+ abort ();
+ bar (a);
+ for (i = 0; i < N / 2; i++)
+ if (a[i] != (i ^ (i * 3 * 512) ^ (((i * 6) + 2) * 512 * 512)))
+ abort ();
+#if 0
+ baz (a + 7);
+ for (i = 0; i < N / 2; i++)
+ if (a[i + 7] != (i ^ (i * 3 * 512) ^ (((i * 6) + 2) * 512 * 512)))
+ abort ();
+ baz (a);
+ for (i = 0; i < N / 2; i++)
+ if (a[i] != (i ^ (i * 3 * 512) ^ (((i * 6) + 2) * 512 * 512)))
+ abort ();
+#endif
+ return 0;
+}
+
+/* { dg-final { cleanup-tree-dump "vect" } } */
--- /dev/null
+/* { dg-require-effective-target vect_simd_clones } */
+/* { dg-additional-options "-fopenmp-simd" } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+/* { dg-additional-sources vect-simd-clone-12a.c } */
+
+#include "vect-simd-clone-10.c"
+
+/* { dg-final { cleanup-tree-dump "vect" } } */
--- /dev/null
+/* { dg-do compile } */
+
+#include "vect-simd-clone-10.h"
+
+#pragma omp declare simd notinbranch
+__attribute__((noinline)) int
+foo (long int a, int b, int c)
+{
+ return a + b + c;
+}
+
+#pragma omp declare simd notinbranch
+__attribute__((noinline)) long int
+bar (int a, int b, long int c)
+{
+ return a + b + c;
+}
--- /dev/null
+/* { dg-require-effective-target vect_simd_clones } */
+/* { dg-additional-options "-fopenmp-simd" } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+
+#include "tree-vect.h"
+
+#ifndef N
+#define N 1024
+#endif
+
+int array[N] __attribute__((aligned (32)));
+
+#pragma omp declare simd simdlen(4) notinbranch aligned(a:16) uniform(a) linear(b)
+#pragma omp declare simd simdlen(4) notinbranch aligned(a:32) uniform(a) linear(b)
+#pragma omp declare simd simdlen(8) notinbranch aligned(a:16) uniform(a) linear(b)
+#pragma omp declare simd simdlen(8) notinbranch aligned(a:32) uniform(a) linear(b)
+__attribute__((noinline)) void
+foo (int *a, int b, int c)
+{
+ a[b] = c;
+}
+
+__attribute__((noinline, noclone)) void
+bar ()
+{
+ int i;
+#pragma omp simd
+ for (i = 0; i < N; ++i)
+ foo (array, i, i * array[i]);
+}
+
+__attribute__((noinline, noclone)) void
+baz ()
+{
+ int i;
+ for (i = 0; i < N; i++)
+ array[i] = 5 * (i & 7);
+}
+
+int
+main ()
+{
+ int i;
+ check_vect ();
+ baz ();
+ bar ();
+ for (i = 0; i < N; i++)
+ if (array[i] != 5 * (i & 7) * i)
+ abort ();
+ return 0;
+}
+
+/* { dg-final { cleanup-tree-dump "vect" } } */
--- /dev/null
+/* { dg-require-effective-target vect_simd_clones } */
+/* { dg-additional-options "-fopenmp-simd" } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+
+#include "tree-vect.h"
+
+#ifndef N
+#define N 1024
+#endif
+
+int d[N], e[N];
+
+#pragma omp declare simd simdlen(4) notinbranch uniform(b) linear(c:3)
+__attribute__((noinline)) int
+foo (int a, int b, int c)
+{
+ if (a < 30)
+ return 5;
+ return a + b + c;
+}
+
+__attribute__((noinline, noclone)) void
+bar ()
+{
+ int i;
+#pragma omp simd
+ for (i = 0; i < N; ++i)
+ {
+ d[i] = foo (i, 123, i * 3);
+ e[i] = e[i] + i;
+ }
+}
+
+int
+main ()
+{
+ int i;
+ check_vect ();
+ bar ();
+ for (i = 0; i < N; i++)
+ if (d[i] != (i < 30 ? 5 : i * 4 + 123) || e[i] != i)
+ abort ();
+ return 0;
+}
+
+/* { dg-final { cleanup-tree-dump "vect" } } */
--- /dev/null
+/* { dg-require-effective-target vect_simd_clones } */
+/* { dg-additional-options "-fopenmp-simd" } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+
+#include "tree-vect.h"
+
+#ifndef N
+#define N 1024
+#endif
+
+float d[N];
+int e[N];
+unsigned short f[N];
+
+#pragma omp declare simd simdlen(8) notinbranch uniform(b)
+__attribute__((noinline)) float
+foo (float a, float b, float c)
+{
+ if (a < 30)
+ return 5.0f;
+ return a + b + c;
+}
+
+__attribute__((noinline, noclone)) void
+bar ()
+{
+ int i;
+#pragma omp simd
+ for (i = 0; i < N; ++i)
+ {
+ d[i] = foo (i, 123, i * 3);
+ e[i] = e[i] * 3;
+ f[i] = f[i] + 1;
+ }
+}
+
+int
+main ()
+{
+ int i;
+ check_vect ();
+ bar ();
+ for (i = 0; i < N; i++)
+ if (d[i] != (i < 30 ? 5.0f : i * 4 + 123.0f) || e[i] || f[i] != 1)
+ abort ();
+ return 0;
+}
+
+/* { dg-final { cleanup-tree-dump "vect" } } */
--- /dev/null
+/* { dg-require-effective-target vect_simd_clones } */
+/* { dg-additional-options "-fopenmp-simd" } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+
+#include "tree-vect.h"
+
+#ifndef N
+#define N 1024
+#endif
+
+int d[N], e[N];
+
+#pragma omp declare simd simdlen(4) notinbranch uniform(b) linear(c:3)
+__attribute__((noinline)) long long int
+foo (int a, int b, int c)
+{
+ return a + b + c;
+}
+
+__attribute__((noinline, noclone)) void
+bar ()
+{
+ int i;
+#pragma omp simd
+ for (i = 0; i < N; ++i)
+ {
+ d[i] = foo (i, 123, i * 3);
+ e[i] = e[i] + i;
+ }
+}
+
+int
+main ()
+{
+ int i;
+ check_vect ();
+ bar ();
+ for (i = 0; i < N; i++)
+ if (d[i] != i * 4 + 123 || e[i] != i)
+ abort ();
+ return 0;
+}
+
+/* { dg-final { cleanup-tree-dump "vect" } } */
--- /dev/null
+/* { dg-require-effective-target vect_simd_clones } */
+/* { dg-additional-options "-fopenmp-simd" } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+
+#include "tree-vect.h"
+
+#ifndef N
+#define N 1024
+#endif
+
+int a[N];
+long long int b[N];
+short c[N];
+
+#pragma omp declare simd
+#pragma omp declare simd uniform(b) linear(c:3)
+__attribute__((noinline)) short
+foo (int a, long long int b, short c)
+{
+ return a + b + c;
+}
+
+__attribute__((noinline, noclone)) void
+bar (int x)
+{
+ int i;
+ if (x == 0)
+ {
+ #pragma omp simd
+ for (i = 0; i < N; i++)
+ c[i] = foo (a[i], b[i], c[i]);
+ }
+ else
+ {
+ #pragma omp simd
+ for (i = 0; i < N; i++)
+ c[i] = foo (a[i], x, i * 3);
+ }
+}
+
+__attribute__((noinline, noclone)) void
+baz (void)
+{
+ int i;
+ for (i = 0; i < N; i++)
+ {
+ a[i] = 2 * i;
+ b[i] = -7 * i + 6;
+ c[i] = (i & 31) << 4;
+ }
+}
+
+int
+main ()
+{
+ int i;
+ check_vect ();
+ baz ();
+ bar (0);
+ for (i = 0; i < N; i++)
+ if (a[i] != 2 * i || b[i] != 6 - 7 * i
+ || c[i] != 6 - 5 * i + ((i & 31) << 4))
+ abort ();
+ else
+ a[i] = c[i];
+ bar (17);
+ for (i = 0; i < N; i++)
+ if (a[i] != 6 - 5 * i + ((i & 31) << 4)
+ || b[i] != 6 - 7 * i
+ || c[i] != 23 - 2 * i + ((i & 31) << 4))
+ abort ();
+ return 0;
+}
+
+/* { dg-final { cleanup-tree-dump "vect" } } */
--- /dev/null
+/* { dg-require-effective-target vect_simd_clones } */
+/* { dg-additional-options "-fopenmp-simd" } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+
+#include "tree-vect.h"
+
+#ifndef N
+#define N 1024
+#endif
+
+int a[N];
+long long int b[N];
+short c[N];
+
+#pragma omp declare simd
+#pragma omp declare simd uniform(b) linear(c:3)
+__attribute__((noinline)) short
+foo (int a, long long int b, int c)
+{
+ return a + b + c;
+}
+
+__attribute__((noinline, noclone)) void
+bar (int x)
+{
+ int i;
+ if (x == 0)
+ {
+ #pragma omp simd
+ for (i = 0; i < N; i++)
+ c[i] = foo (a[i], b[i], c[i]);
+ }
+ else
+ {
+ #pragma omp simd
+ for (i = 0; i < N; i++)
+ c[i] = foo (a[i], x, i * 3);
+ }
+}
+
+__attribute__((noinline, noclone)) void
+baz (void)
+{
+ int i;
+ for (i = 0; i < N; i++)
+ {
+ a[i] = 2 * i;
+ b[i] = -7 * i + 6;
+ c[i] = (i & 31) << 4;
+ }
+}
+
+int
+main ()
+{
+ int i;
+ check_vect ();
+ baz ();
+ bar (0);
+ for (i = 0; i < N; i++)
+ if (a[i] != 2 * i || b[i] != 6 - 7 * i
+ || c[i] != 6 - 5 * i + ((i & 31) << 4))
+ abort ();
+ else
+ a[i] = c[i];
+ bar (17);
+ for (i = 0; i < N; i++)
+ if (a[i] != 6 - 5 * i + ((i & 31) << 4)
+ || b[i] != 6 - 7 * i
+ || c[i] != 23 - 2 * i + ((i & 31) << 4))
+ abort ();
+ return 0;
+}
+
+/* { dg-final { cleanup-tree-dump "vect" } } */
--- /dev/null
+/* { dg-require-effective-target vect_simd_clones } */
+/* { dg-additional-options "-fopenmp-simd" } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+
+#include "tree-vect.h"
+
+#ifndef N
+#define N 1024
+#endif
+
+int a[N], b[N];
+long int c[N];
+unsigned char d[N];
+
+#pragma omp declare simd simdlen(8) notinbranch
+__attribute__((noinline)) int
+foo (long int a, int b, int c)
+{
+ return a + b + c;
+}
+
+#pragma omp declare simd simdlen(8) notinbranch
+__attribute__((noinline)) long int
+bar (int a, int b, long int c)
+{
+ return a + b + c;
+}
+
+__attribute__((noinline)) void
+fn1 (void)
+{
+ int i;
+ #pragma omp simd
+ for (i = 0; i < N; i++)
+ a[i] = foo (c[i], a[i], b[i]) + 6;
+ #pragma omp simd
+ for (i = 0; i < N; i++)
+ c[i] = bar (a[i], b[i], c[i]) * 2;
+}
+
+__attribute__((noinline)) void
+fn2 (void)
+{
+ int i;
+ #pragma omp simd
+ for (i = 0; i < N; i++)
+ {
+ a[i] = foo (c[i], a[i], b[i]) + 6;
+ d[i]++;
+ }
+ #pragma omp simd
+ for (i = 0; i < N; i++)
+ {
+ c[i] = bar (a[i], b[i], c[i]) * 2;
+ d[i] /= 2;
+ }
+}
+
+__attribute__((noinline)) void
+fn3 (void)
+{
+ int i;
+ for (i = 0; i < N; i++)
+ {
+ a[i] = i * 2;
+ b[i] = 17 + (i % 37);
+ c[i] = (i & 63);
+ d[i] = 16 + i;
+ }
+}
+
+int
+main ()
+{
+ int i;
+ check_vect ();
+ fn3 ();
+ fn1 ();
+ for (i = 0; i < N; i++)
+ if (a[i] != i * 2 + 23 + (i % 37) + (i & 63)
+ || b[i] != 17 + (i % 37)
+ || c[i] != i * 4 + 80 + 4 * (i % 37) + 4 * (i & 63))
+ abort ();
+ fn3 ();
+ fn2 ();
+ for (i = 0; i < N; i++)
+ if (a[i] != i * 2 + 23 + (i % 37) + (i & 63)
+ || b[i] != 17 + (i % 37)
+ || c[i] != i * 4 + 80 + 4 * (i % 37) + 4 * (i & 63)
+ || d[i] != ((unsigned char) (17 + i)) / 2)
+ abort ();
+ return 0;
+}
+
+/* { dg-final { cleanup-tree-dump "vect" } } */
--- /dev/null
+/* { dg-require-effective-target vect_simd_clones } */
+/* { dg-additional-options "-fopenmp-simd" } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+
+#include "tree-vect.h"
+
+#ifndef N
+#define N 1024
+#endif
+
+int a[N], b[N];
+long int c[N];
+unsigned char d[N];
+
+#pragma omp declare simd notinbranch
+__attribute__((noinline)) static int
+foo (long int a, int b, int c)
+{
+ return a + b + c;
+}
+
+#pragma omp declare simd notinbranch
+__attribute__((noinline)) static long int
+bar (int a, int b, long int c)
+{
+ return a + b + c;
+}
+
+__attribute__((noinline)) void
+fn1 (void)
+{
+ int i;
+ #pragma omp simd
+ for (i = 0; i < N; i++)
+ a[i] = foo (c[i], a[i], b[i]) + 6;
+ #pragma omp simd
+ for (i = 0; i < N; i++)
+ c[i] = bar (a[i], b[i], c[i]) * 2;
+}
+
+__attribute__((noinline)) void
+fn2 (void)
+{
+ int i;
+ #pragma omp simd
+ for (i = 0; i < N; i++)
+ {
+ a[i] = foo (c[i], a[i], b[i]) + 6;
+ d[i]++;
+ }
+ #pragma omp simd
+ for (i = 0; i < N; i++)
+ {
+ c[i] = bar (a[i], b[i], c[i]) * 2;
+ d[i] /= 2;
+ }
+}
+
+__attribute__((noinline)) void
+fn3 (void)
+{
+ int i;
+ for (i = 0; i < N; i++)
+ {
+ a[i] = i * 2;
+ b[i] = 17 + (i % 37);
+ c[i] = (i & 63);
+ d[i] = 16 + i;
+ }
+}
+
+int
+main ()
+{
+ int i;
+ check_vect ();
+ fn3 ();
+ fn1 ();
+ for (i = 0; i < N; i++)
+ if (a[i] != i * 2 + 23 + (i % 37) + (i & 63)
+ || b[i] != 17 + (i % 37)
+ || c[i] != i * 4 + 80 + 4 * (i % 37) + 4 * (i & 63))
+ abort ();
+ fn3 ();
+ fn2 ();
+ for (i = 0; i < N; i++)
+ if (a[i] != i * 2 + 23 + (i % 37) + (i & 63)
+ || b[i] != 17 + (i % 37)
+ || c[i] != i * 4 + 80 + 4 * (i % 37) + 4 * (i & 63)
+ || d[i] != ((unsigned char) (17 + i)) / 2)
+ abort ();
+ return 0;
+}
+
+/* { dg-final { cleanup-tree-dump "vect" } } */
# Main loop.
set VECT_ADDITIONAL_FLAGS [list ""]
if { [check_effective_target_lto] } {
- lappend VECT_ADDITIONAL_FLAGS "-flto"
+ lappend VECT_ADDITIONAL_FLAGS "-flto -ffat-lto-objects"
}
foreach flags $VECT_ADDITIONAL_FLAGS {
dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/pr*.\[cS\]]] \
--- /dev/null
+/* Test vmov_n works correctly. */
+/* { dg-do run } */
+/* { dg-options "-O3 --save-temps" } */
+
+#include <arm_neon.h>
+
+extern void abort (void);
+
+#define INHIB_OPTIMIZATION asm volatile ("" : : : "memory")
+
+#define CONCAT(a, b) a##b
+#define CONCAT1(a, b) CONCAT (a, b)
+#define REG_INFEX64 _
+#define REG_INFEX128 q_
+#define REG_INFEX(reg_len) REG_INFEX##reg_len
+#define POSTFIX_N(reg_len, data_len, data_type) \
+ CONCAT1 (REG_INFEX (reg_len), n_##data_type##data_len)
+#define LANE_POSTFIX(reg_len, data_len, data_type) \
+ CONCAT1 (REG_INFEX (reg_len),lane_##data_type##data_len)
+
+/* Test values consist of bytes with following hex values.
+ For example:
+ TEST1 for int16_t will be 0xaaaa
+ TEST1 for int32_t will be 0xaaaaaaaa
+ etc. */
+
+#define TEST1h aa
+#define TEST2h 55
+#define TEST3h ff
+#define TEST4h 00
+#define TEST5h cc
+#define TEST6h 33
+
+#define TESTh_8(x) TEST##x##h
+#define TESTh_16(x) CONCAT1 (TESTh_8 (x), TESTh_8 (x))
+#define TESTh_32(x) CONCAT1 (TESTh_16 (x), TESTh_16 (x))
+#define TESTh_64(x) CONCAT1 (TESTh_32 (x), TESTh_32 (x))
+
+#define TEST_8(x) CONCAT1 (0x, TESTh_8 (x))
+#define TEST_16(x) CONCAT1 (0x, TESTh_16 (x))
+#define TEST_32(x) CONCAT1 (0x, TESTh_32 (x))
+#define TEST_64(x) CONCAT1 (0x, TESTh_64 (x))
+
+#define TEST(test, data_len) \
+ CONCAT1 (TEST, _##data_len) (test)
+
+#define GET_ELEMENT(reg_len, data_len, data_type) \
+ CONCAT1 (vget, LANE_POSTFIX (reg_len, data_len, data_type))
+
+#define VMOV_INST(reg_len, data_len, data_type) \
+ CONCAT1 (vmov, POSTFIX_N (reg_len, data_len, data_type))
+
+#define VMOV_OBSCURE_INST(reg_len, data_len, data_type) \
+ CONCAT1 (VMOV_INST (reg_len, data_len, data_type), _obscure)
+
+#define RUN_TEST(reg_len, data_len, data_type, \
+ test, n, a, b, c) \
+{ \
+ int i; \
+ INHIB_OPTIMIZATION; \
+ (a) = TEST (test, data_len); \
+ INHIB_OPTIMIZATION; \
+ (b) = VMOV_OBSCURE_INST (reg_len, data_len, data_type) (&(a)); \
+ (c) = TEST (test, data_len); \
+ for (i = 0; i < n; i++) \
+ { \
+ INHIB_OPTIMIZATION; \
+ a = GET_ELEMENT (reg_len, data_len, data_type) (b, i); \
+ if ((a) != (c)) \
+ return 1; \
+ } \
+}
+
+#define TYPE_f32 float32_t
+#define TYPE_64_f32 float32x2_t
+#define TYPE_128_f32 float32x4_t
+
+#define TYPE_f64 float64_t
+#define TYPE_64_f64 float64x1_t
+#define TYPE_128_f64 float64x2_t
+
+#define TYPE_s8 int8_t
+#define TYPE_64_s8 int8x8_t
+#define TYPE_128_s8 int8x16_t
+
+#define TYPE_s16 int16_t
+#define TYPE_64_s16 int16x4_t
+#define TYPE_128_s16 int16x8_t
+
+#define TYPE_s32 int32_t
+#define TYPE_64_s32 int32x2_t
+#define TYPE_128_s32 int32x4_t
+
+#define TYPE_s64 int64_t
+#define TYPE_64_s64 int64x1_t
+#define TYPE_128_s64 int64x2_t
+
+#define TYPE_u8 uint8_t
+#define TYPE_64_u8 uint8x8_t
+#define TYPE_128_u8 uint8x16_t
+
+#define TYPE_u16 uint16_t
+#define TYPE_64_u16 uint16x4_t
+#define TYPE_128_u16 uint16x8_t
+
+#define TYPE_u32 uint32_t
+#define TYPE_64_u32 uint32x2_t
+#define TYPE_128_u32 uint32x4_t
+
+#define TYPE_u64 uint64_t
+#define TYPE_64_u64 uint64x1_t
+#define TYPE_128_u64 uint64x2_t
+
+#define TYPE_p8 poly8_t
+#define TYPE_64_p8 poly8x8_t
+#define TYPE_128_p8 poly8x16_t
+
+#define TYPE_p16 poly16_t
+#define TYPE_64_p16 poly16x4_t
+#define TYPE_128_p16 poly16x8_t
+
+#define DIV64_8 8
+#define DIV64_16 4
+#define DIV64_32 2
+#define DIV64_64 1
+
+#define DIV128_8 16
+#define DIV128_16 8
+#define DIV128_32 4
+#define DIV128_64 2
+
+#define DIV(reg_len, data_len) \
+CONCAT1 (CONCAT1 (DIV, reg_len), \
+ CONCAT1 (_, data_len))
+
+#define VECTOR_TYPE(reg_len, data_len, data_type) \
+CONCAT1 (CONCAT1 (CONCAT1 (TYPE_,reg_len), \
+ CONCAT1 (_,data_type)), \
+ data_len)
+
+#define SIMPLE_TYPE(data_len, data_type) \
+CONCAT1 (TYPE_, \
+ CONCAT1 (data_type, \
+ data_len))
+
+#define OBSCURE_FUNC_NAME(reg_len, data_type, data_len) \
+CONCAT1 (CONCAT1 (vmov, \
+ POSTFIX_N (reg_len, data_len, data_type)), \
+ _obscure)
+
+#define OBSCURE_FUNC(reg_len, data_len, data_type) \
+VECTOR_TYPE (reg_len, data_len, data_type) \
+__attribute__ ((noinline)) \
+OBSCURE_FUNC_NAME (reg_len, data_type, data_len) \
+ (SIMPLE_TYPE (data_len, data_type) *ap) \
+{ \
+ SIMPLE_TYPE (data_len, data_type) register a; \
+ INHIB_OPTIMIZATION; \
+ a = *ap; \
+ INHIB_OPTIMIZATION; \
+ return VMOV_INST (reg_len, data_len, data_type) (a); \
+}
+
+#define TESTFUNC_NAME(reg_len, data_type, data_len) \
+CONCAT1 (test_vmov, \
+ POSTFIX_N (reg_len, data_len, data_type))
+
+#define TESTFUNC(reg_len, data_len, data_type) \
+int \
+TESTFUNC_NAME (reg_len, data_type, data_len) () \
+{ \
+ SIMPLE_TYPE (data_len, data_type) a; \
+ VECTOR_TYPE (reg_len, data_len, data_type) b; \
+ SIMPLE_TYPE (data_len, data_type) c; \
+ \
+ RUN_TEST (reg_len, data_len, data_type, 1, \
+ DIV (reg_len, data_len), a, b, c); \
+ RUN_TEST (reg_len, data_len, data_type, 2, \
+ DIV (reg_len, data_len), a, b, c); \
+ RUN_TEST (reg_len, data_len, data_type, 3, \
+ DIV (reg_len, data_len), a, b, c); \
+ RUN_TEST (reg_len, data_len, data_type, 4, \
+ DIV (reg_len, data_len), a, b, c); \
+ RUN_TEST (reg_len, data_len, data_type, 5, \
+ DIV (reg_len, data_len), a, b, c); \
+ RUN_TEST (reg_len, data_len, data_type, 6, \
+ DIV (reg_len, data_len), a, b, c); \
+ return 0; \
+}
+
+OBSCURE_FUNC (64, 32, f)
+TESTFUNC (64, 32, f)
+/* "dup Vd.2s, Rn" is less preferable then "dup Vd.2s, Vn.s[lane]". */
+/* { dg-final { scan-assembler-times "dup\\tv\[0-9\]+\.2s, v\[0-9\]+\.s\\\[\[0-9\]+\\\]" 1 } } */
+
+OBSCURE_FUNC (64, 64, f)
+TESTFUNC (64, 64, f)
+/* "fmov Dd, Rn" is generated instead of "dup Dd, Rn".
+ No assembley scan included. */
+
+OBSCURE_FUNC (64, 8, p)
+TESTFUNC (64, 8, p)
+/* Generates "dup Vd.8b, Rn". Scan found near s8 version. */
+
+OBSCURE_FUNC (64, 16, p)
+TESTFUNC (64, 16, p)
+/* Generates "dup Vd.4h, Rn". Scan found near s16 version. */
+
+OBSCURE_FUNC (64, 8, s)
+TESTFUNC (64, 8, s)
+/* { dg-final { scan-assembler-times "dup\\tv\[0-9\]+\.8b, w\[0-9\]+" 3 } } */
+
+OBSCURE_FUNC (64, 16, s)
+TESTFUNC (64, 16, s)
+/* { dg-final { scan-assembler-times "dup\\tv\[0-9\]+\.4h, w\[0-9\]+" 3 } } */
+
+OBSCURE_FUNC (64, 32, s)
+TESTFUNC (64, 32, s)
+/* { dg-final { scan-assembler-times "dup\\tv\[0-9\]+\.2s, w\[0-9\]+" 2 } } */
+
+OBSCURE_FUNC (64, 64, s)
+TESTFUNC (64, 64, s)
+/* "fmov Dd, Rn" is generated instead of "dup Dd, Rn".
+ No assembley scan included. */
+
+OBSCURE_FUNC (64, 8, u)
+TESTFUNC (64, 8, u)
+/* Generates "dup Vd.8b, Rn". Scan found near s8 version. */
+
+OBSCURE_FUNC (64, 16, u)
+TESTFUNC (64, 16, u)
+/* Generates "dup Vd.4h, Rn". Scan found near s16 version. */
+
+OBSCURE_FUNC (64, 32, u)
+TESTFUNC (64, 32, u)
+/* Generates "dup Vd.2s, Rn". Scan found near s32 version. */
+
+OBSCURE_FUNC (64, 64, u)
+TESTFUNC (64, 64, u)
+/* "fmov Dd, Rn" is generated instead of "dup Dd, Rn".
+ No assembley scan included. */
+
+OBSCURE_FUNC (128, 32, f)
+TESTFUNC (128, 32, f)
+/* "dup Vd.4s, Rn" is less preferable then "dup Vd.4s, Vn.s[lane]". */
+/* { dg-final { scan-assembler-times "dup\\tv\[0-9\]+\.4s, v\[0-9\]+\.s\\\[\[0-9\]+\\\]" 1 } } */
+
+OBSCURE_FUNC (128, 64, f)
+TESTFUNC (128, 64, f)
+/* "dup Vd.2d, Rn" is less preferable then "dup Vd.2d, Vn.d[lane]". */
+/* { dg-final { scan-assembler-times "dup\\tv\[0-9\]+\.2d, v\[0-9\]+\.d\\\[\[0-9\]+\\\]" 1 } } */
+
+OBSCURE_FUNC (128, 8, p)
+TESTFUNC (128, 8, p)
+/* Generates "dup Vd.16b, Rn". Scan found near s8 version. */
+
+OBSCURE_FUNC (128, 16, p)
+TESTFUNC (128, 16, p)
+/* Generates "dup Vd.8h, Rn". Scan found near s16 version. */
+
+OBSCURE_FUNC (128, 8, s)
+TESTFUNC (128, 8, s)
+/* { dg-final { scan-assembler-times "dup\\tv\[0-9\]+\.16b, w\[0-9\]+" 3 } } */
+
+OBSCURE_FUNC (128, 16, s)
+TESTFUNC (128, 16, s)
+/* { dg-final { scan-assembler-times "dup\\tv\[0-9\]+\.8h, w\[0-9\]+" 3 } } */
+
+OBSCURE_FUNC (128, 32, s)
+TESTFUNC (128, 32, s)
+/* { dg-final { scan-assembler-times "dup\\tv\[0-9\]+\.4s, w\[0-9\]+" 2 } } */
+
+OBSCURE_FUNC (128, 64, s)
+TESTFUNC (128, 64, s)
+/* { dg-final { scan-assembler-times "dup\\tv\[0-9\]+\.2d, x\[0-9\]+" 2 } } */
+
+OBSCURE_FUNC (128, 8, u)
+TESTFUNC (128, 8, u)
+/* Generates "dup Vd.16b, Rn". Scan found near s8 version. */
+
+OBSCURE_FUNC (128, 16, u)
+TESTFUNC (128, 16, u)
+/* Generates "dup Vd.8h, Rn". Scan found near s16 version. */
+
+OBSCURE_FUNC (128, 32, u)
+TESTFUNC (128, 32, u)
+/* Generates "dup Vd.4s, Rn". Scan found near s32 version. */
+
+OBSCURE_FUNC (128, 64, u)
+TESTFUNC (128, 64, u)
+/* Generates "dup Vd.2d, Rn". Scan found near s64 version. */
+
+int
+main (int argc, char **argv)
+{
+ if (test_vmov_n_f32 ())
+ abort ();
+ if (test_vmov_n_f64 ())
+ abort ();
+ if (test_vmov_n_p8 ())
+ abort ();
+ if (test_vmov_n_p16 ())
+ abort ();
+ if (test_vmov_n_s8 ())
+ abort ();
+ if (test_vmov_n_s16 ())
+ abort ();
+ if (test_vmov_n_s32 ())
+ abort ();
+ if (test_vmov_n_s64 ())
+ abort ();
+ if (test_vmov_n_u8 ())
+ abort ();
+ if (test_vmov_n_u16 ())
+ abort ();
+ if (test_vmov_n_u32 ())
+ abort ();
+ if (test_vmov_n_u64 ())
+ abort ();
+
+ if (test_vmovq_n_f32 ())
+ abort ();
+ if (test_vmovq_n_f64 ())
+ abort ();
+ if (test_vmovq_n_p8 ())
+ abort ();
+ if (test_vmovq_n_p16 ())
+ abort ();
+ if (test_vmovq_n_s8 ())
+ abort ();
+ if (test_vmovq_n_s16 ())
+ abort ();
+ if (test_vmovq_n_s32 ())
+ abort ();
+ if (test_vmovq_n_s64 ())
+ abort ();
+ if (test_vmovq_n_u8 ())
+ abort ();
+ if (test_vmovq_n_u16 ())
+ abort ();
+ if (test_vmovq_n_u32 ())
+ abort ();
+ if (test_vmovq_n_u64 ())
+ abort ();
+
+ return 0;
+}
+
+/* { dg-final { cleanup-saved-temps } } */
--- /dev/null
+/* Check that CONST_INT is not forced into REG before PLUS. */
+/* { dg-do compile { target { arm_arm_ok || arm_thumb2_ok} } } */
+/* { dg-options "-O2 -fdump-rtl-expand" } */
+
+typedef int Arr2[50][50];
+
+void
+foo (Arr2 a2, int i)
+{
+ a2[i+20][i] = 1;
+}
+
+/* { dg-final { scan-rtl-dump-not "\\\(set \\\(reg:SI \[0-9\]*\\\)\[\n\r\]+\[ \t]*\\\(const_int 4000" "expand" } } */
+/* { dg-final { cleanup-rtl-dump "expand" } } */
/* { dg-do compile { target arm_thumb2 } } */
/* { dg-options "-O2 -fdump-rtl-subreg2" } */
-/* { dg-final { scan-rtl-dump "REG_INC" "subreg2" } } */
+/* { dg-final { scan-rtl-dump "REG_INC" "subreg2" { target { ! arm_neon } } } } */
/* { dg-final { cleanup-rtl-dump "subreg2" } } */
struct device;
typedef unsigned int __u32;
rsb r0, r0, #0
mov r1, #0
*/
-/* { dg-final { scan-assembler-times "rsb\\tr0, r0, #0" 1 { target { arm_nothumb } } } } */
-/* { dg-final { scan-assembler-times "negs\\tr0, r0" 1 { target { ! arm_nothumb } } } } */
+/* { dg-final { scan-assembler-times "rsb\\t...?, ...?, #0" 1 { target { arm_nothumb } } } } */
+/* { dg-final { scan-assembler-times "negs\\t...?, ...?" 1 { target { ! arm_nothumb } } } } */
/* { dg-final { scan-assembler-times "mov" 1 } } */
+++ /dev/null
-/* { dg-do compile } */
-/* { dg-require-effective-target arm32 } */
-/* { dg-options "-O2" } */
-
-signed long long negdi_extendsidi (signed int x)
-{
- return -((signed long long) x);
-}
-/*
-Expected output:
- rsbs r0, r0, #0
- mov r1, r0, asr #31
-*/
-/* { dg-final { scan-assembler-times "rsb" 1 } } */
-/* { dg-final { scan-assembler-times "asr" 1 } } */
-/* { dg-final { scan-assembler-times "rsc" 0 } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_thumb1_ok } */
+/* { dg-options "-mthumb -fpic -mpic-register=9" } */
+
+int g_test;
+
+int
+foo (int par)
+{
+ g_test = par;
+}
--- /dev/null
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_thumb1_ok } */
+/* { dg-options "-mthumb -fpic -msingle-pic-base" } */
+
+int g_test;
+
+int
+foo (int par)
+{
+ g_test = par;
+}
--- /dev/null
+/* The option -mslow-flash-data is just for performance tuning, it
+ doesn't totally disable the use of literal pools. But for below
+ simple cases, the use of literal pool should be replaced by
+ movw/movt or read-only constant pool. */
+
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_cortex_m } */
+/* { dg-require-effective-target arm_thumb2_ok } */
+/* { dg-options "-O2 -mthumb -mslow-flash-data" } */
+
+float sf;
+double df;
+long long l;
+static char *p = "Hello World";
+
+float
+testsf (float *p)
+{
+ if (*p > 1.1234f)
+ return 2.1234f;
+ else
+ return 3.1234f;
+}
+
+double
+testdf (double *p)
+{
+ if (*p > 4.1234)
+ return 2.1234;
+ else
+ return 3.1234;
+}
+
+long long
+testll (long long *p)
+{
+ if (*p > 0x123456789ABCDEFll)
+ return 0x111111111ll;
+ else
+ return 0x222222222ll;
+}
+
+char *
+testchar ()
+{
+ return p + 4;
+}
+
+int
+foo (int a, int b)
+{
+ int i;
+ volatile *labelref = &&label1;
+
+ if (a > b)
+ {
+ while (i < b)
+ {
+ a += *labelref;
+ i += 1;
+ }
+ goto *labelref;
+ }
+ else
+ b = b + 3;
+
+ a = a * b;
+
+label1:
+ return a + b;
+}
+
+/* { dg-final { scan-assembler-times "movt" 13 } } */
+/* { dg-final { scan-assembler-times "movt.*LC0\\+4" 1 } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_v8_vfp_ok } */
+/* { dg-options "-O2 -marm -march=armv8-a" } */
+/* { dg-add-options arm_v8_vfp } */
+
+double foo (double a)
+{
+ if (a > 3.0)
+ return __builtin_round (a);
+
+ return 0.0;
+}
+
+/* { dg-final { scan-assembler-times "vrinta.f64\td\[0-9\]+" 1 } } */
+
} "-mlzcnt" ]
}
-# Return 1 if avx2 instructions can be compiled.
-proc check_effective_target_avx2 { } {
- return [check_no_compiler_messages avx2 object {
- typedef long long __v4di __attribute__ ((__vector_size__ (32)));
- __v4di
- mm256_is32_andnotsi256 (__v4di __X, __v4di __Y)
- {
- return __builtin_ia32_andnotsi256 (__X, __Y);
- }
- } "-O0 -mavx2" ]
-}
-
# Return 1 if bmi instructions can be compiled.
proc check_effective_target_bmi { } {
return [check_no_compiler_messages bmi object {
--- /dev/null
+/* { dg-do compile { target { ia32 } } } */
+/* { dg-options "-O2 -fomit-frame-pointer" } */
+/* { dg-final { scan-assembler-not "%ebp" } } */
+
+__attribute__((__noinline__, __noclone__, __stdcall__)) void g(int a)
+{
+ __builtin_printf("in g(): %d\n", a);
+}
+
+__attribute__((__noinline__, __noclone__, __thiscall__)) void h(int a, int b)
+{
+ __builtin_printf("in h(): %d %d\n", a, b);
+}
+
+void f()
+{
+ g(0);
+ h(0, 1);
+ __builtin_puts("in f()");
+}
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O -fpeel-loops" } */
+
+extern char outbuffer[];
+extern char buffer[];
+
+void foo(int j)
+{
+ unsigned i, fp = fp;
+ for (i = 0; i < 6; i++)
+ buffer[j++] = outbuffer[fp - i];
+}
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-Wunused-macros -march=native" } */
+
+#pragma GCC push_options
+#pragma GCC target("xsaveopt")
+void fn1(void) {}
+#pragma GCC pop_options
+
+/* { dg-prune-output "macro \"__code_model_" } */
+/* { dg-prune-output "macro \"__XSAVE__\" is not used" } */
+/* { dg-prune-output "macro \"__XSAVEOPT__\" is not used" } */
--- /dev/null
+/* PR target/59363 */
+/* { dg-do run } */
+/* { dg-options "-O2 -mtune=amdfam10" } */
+
+typedef struct {
+ int ctxlen;
+ long interhunkctxlen;
+ int flags;
+ long find_func;
+ void *find_func_priv;
+ int hunk_func;
+} xdemitconf_t;
+
+__attribute__((noinline))
+int xdi_diff(xdemitconf_t *xecfg) {
+ if (xecfg->hunk_func == 0)
+ __builtin_abort();
+ return 0;
+}
+int main() {
+ xdemitconf_t xecfg = {0};
+ xecfg.hunk_func = 1;
+ return xdi_diff(&xecfg);
+}
--- /dev/null
+/* { dg-do run } */
+/* { dg-require-effective-target xop } */
+/* { dg-options "-O2 -mxop" } */
+
+#include "xop-check.h"
+
+#include <x86intrin.h>
+
+void
+check_mm_vmfrcz_sd (__m128d __A, __m128d __B)
+{
+ union128d a, b, c;
+ double d[2];
+
+ a.x = __A;
+ b.x = __B;
+ c.x = _mm_frcz_sd (__A, __B);
+ d[0] = b.a[0] - (int)b.a[0] ;
+ d[1] = a.a[1];
+ if (check_union128d (c, d))
+ abort ();
+}
+
+void
+check_mm_vmfrcz_ss (__m128 __A, __m128 __B)
+{
+ union128 a, b, c;
+ float f[4];
+
+ a.x = __A;
+ b.x = __B;
+ c.x = _mm_frcz_ss (__A, __B);
+ f[0] = b.a[0] - (int)b.a[0] ;
+ f[1] = a.a[1];
+ f[2] = a.a[2];
+ f[3] = a.a[3];
+ if (check_union128 (c, f))
+ abort ();
+}
+
+static void
+xop_test (void)
+{
+ union128 a, b;
+ union128d c,d;
+ int i;
+
+ for (i = 0; i < 4; i++)
+ {
+ a.a[i] = i + 3.5;
+ b.a[i] = i + 7.9;
+ }
+ for (i = 0; i < 2; i++)
+ {
+ c.a[i] = i + 3.5;
+ d.a[i] = i + 7.987654321;
+ }
+ check_mm_vmfrcz_ss (a.x, b.x);
+ check_mm_vmfrcz_sd (c.x, d.x);
+}
--- /dev/null
+/* This is a basic main function test program. */
+
+/* { dg-do run } */
+/* { dg-options "-O0" } */
+
+int main(void)
+{
+ return 0;
+}
--- /dev/null
+/* Verify that we generate isb instruction with builtin function. */
+
+/* { dg-do compile } */
+/* { dg-options "-O0" } */
+/* { dg-final { scan-assembler "\\tisb" } } */
+
+void
+test (void)
+{
+ __builtin_nds32_isb ();
+}
--- /dev/null
+/* Verify that we generate isync instruction with builtin function. */
+
+/* { dg-do compile } */
+/* { dg-options "-O0" } */
+/* { dg-final { scan-assembler "\\tisync" } } */
+
+void
+test (void)
+{
+ int *addr = (int *) 0x53000000;
+ __builtin_nds32_isync (addr);
+}
--- /dev/null
+/* Verify that we generate mfsr/mtsr instruction with builtin function. */
+
+/* { dg-do compile } */
+/* { dg-options "-O0" } */
+/* { dg-final { scan-assembler "\\tmfsr" } } */
+/* { dg-final { scan-assembler "\\tmtsr" } } */
+
+#include <nds32_intrinsic.h>
+
+void
+test (void)
+{
+ int ipsw_value;
+
+ ipsw_value = __builtin_nds32_mfsr (__NDS32_REG_IPSW__);
+ __builtin_nds32_mtsr (ipsw_value, __NDS32_REG_IPSW__);
+}
--- /dev/null
+/* Verify that we generate mfusr/mtusr instruction with builtin function. */
+
+/* { dg-do compile } */
+/* { dg-options "-O0" } */
+/* { dg-final { scan-assembler "\\tmfusr" } } */
+/* { dg-final { scan-assembler "\\tmtusr" } } */
+
+#include <nds32_intrinsic.h>
+
+void
+test (void)
+{
+ int itype_value;
+
+ itype_value = __builtin_nds32_mfusr (__NDS32_REG_ITYPE__);
+ __builtin_nds32_mtusr (itype_value, __NDS32_REG_ITYPE__);
+}
--- /dev/null
+/* Verify that we generate setgie.d instruction with builtin function. */
+
+/* { dg-do compile } */
+/* { dg-options "-O0" } */
+/* { dg-final { scan-assembler "\\tsetgie.d" } } */
+
+void
+test (void)
+{
+ __builtin_nds32_setgie_dis ();
+}
--- /dev/null
+/* Verify that we generate setgie.e instruction with builtin function. */
+
+/* { dg-do compile } */
+/* { dg-options "-O0" } */
+/* { dg-final { scan-assembler "\\tsetgie.e" } } */
+
+void
+test (void)
+{
+ __builtin_nds32_setgie_en ();
+}
--- /dev/null
+# Target test cases of Andes NDS32 cpu for GNU compiler
+# Copyright (C) 2012-2013 Free Software Foundation, Inc.
+# Contributed by Andes Technology Corporation.
+#
+# This file is part of GCC.
+#
+# GCC is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published
+# by the Free Software Foundation; either version 3, or (at your
+# option) any later version.
+#
+# GCC is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+# License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+# GCC testsuite that uses the `dg.exp' driver.
+
+# Exit immediately if this isn't a nds32 target.
+if ![istarget nds32*-*-*] then {
+ return
+}
+
+# Load support procs.
+load_lib gcc-dg.exp
+
+# If a testcase doesn't have special options, use these.
+global DEFAULT_CFLAGS
+if ![info exists DEFAULT_CFLAGS] then {
+ set DEFAULT_CFLAGS " -ansi -pedantic-errors"
+}
+
+# Initialize `dg'.
+dg-init
+
+# Main loop.
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] \
+ "" $DEFAULT_CFLAGS
+
+# All done.
+dg-finish
-/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
/* { dg-require-effective-target powerpc_altivec_ok } */
/* { dg-options "-O2 -mcpu=power6 -mabi=altivec -maltivec -mno-vsx" } */
-/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
/* { dg-require-effective-target powerpc_vsx_ok } */
/* { dg-options "-O2 -mcpu=power7" } */
-/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
/* { dg-require-effective-target powerpc_p8vector_ok } */
/* { dg-options "-O2 -mcpu=power8" } */
/* { dg-skip-if "" { powerpc*-*-*spe* } { "*" } { "" } } */
/* { dg-require-effective-target powerpc_p8vector_ok } */
/* { dg-options "-mcpu=power8 -O2" } */
-/* { dg-final { scan-assembler-times "mtvsrd" 1 } } */
-/* { dg-final { scan-assembler-times "mfvsrd" 1 } } */
+/* { dg-final { scan-assembler "mtvsrd" } } */
+/* { dg-final { scan-assembler "mfvsrd" } } */
-/* Check code generation for direct move for long types. */
+/* Check code generation for direct move for double types. */
#define TYPE double
#define IS_FLOAT 1
#define NO_ALTIVEC 1
+#define VSX_REG_ATTR "ws"
#include "direct-move.h"
#define IS_FLOAT 1
#define NO_ALTIVEC 1
#define DO_MAIN
+#define VSX_REG_ATTR "ws"
#include "direct-move.h"
/* { dg-skip-if "" { powerpc*-*-*spe* } { "*" } { "" } } */
/* { dg-require-effective-target powerpc_p8vector_ok } */
/* { dg-options "-mcpu=power8 -O2" } */
-/* { dg-final { scan-assembler-times "mtvsrd" 2 } } */
-/* { dg-final { scan-assembler-times "mfvsrd" 2 } } */
-/* { dg-final { scan-assembler-times "xscvdpspn" 2 } } */
-/* { dg-final { scan-assembler-times "xscvspdpn" 2 } } */
+/* { dg-final { scan-assembler "mtvsrd" } } */
+/* { dg-final { scan-assembler "mfvsrd" } } */
+/* { dg-final { scan-assembler "xscvdpspn" } } */
+/* { dg-final { scan-assembler "xscvspdpn" } } */
-/* Check code generation for direct move for long types. */
+/* Check code generation for direct move for float types. */
#define TYPE float
#define IS_FLOAT 1
#define NO_ALTIVEC 1
+#define VSX_REG_ATTR "ww"
#include "direct-move.h"
#define IS_FLOAT 1
#define NO_ALTIVEC 1
#define DO_MAIN
+#define VSX_REG_ATTR "ww"
#include "direct-move.h"
/* { dg-skip-if "" { powerpc*-*-*spe* } { "*" } { "" } } */
/* { dg-require-effective-target powerpc_p8vector_ok } */
/* { dg-options "-mcpu=power8 -O2" } */
-/* { dg-final { scan-assembler-times "mtvsrd" 1 } } */
-/* { dg-final { scan-assembler-times "mfvsrd" 2 } } */
+/* { dg-final { scan-assembler "mtvsrd" } } */
+/* { dg-final { scan-assembler "mfvsrd" } } */
/* Check code generation for direct move for long types. */
#define TYPE long
#define IS_INT 1
#define NO_ALTIVEC 1
+#define VSX_REG_ATTR "d"
#include "direct-move.h"
#define IS_INT 1
#define NO_ALTIVEC 1
#define DO_MAIN
+#define VSX_REG_ATTR "d"
#include "direct-move.h"
/* { dg-skip-if "" { powerpc*-*-*spe* } { "*" } { "" } } */
/* { dg-require-effective-target powerpc_p8vector_ok } */
/* { dg-options "-mcpu=power8 -O2" } */
-/* { dg-final { scan-assembler-times "mtvsrd" 4 } } */
-/* { dg-final { scan-assembler-times "mfvsrd" 4 } } */
+/* { dg-final { scan-assembler "mtvsrd" } } */
+/* { dg-final { scan-assembler "mfvsrd" } } */
-/* Check code generation for direct move for long types. */
+/* Check code generation for direct move for vector types. */
#define TYPE vector int
+#define VSX_REG_ATTR "wa"
#include "direct-move.h"
#define TYPE vector int
#define DO_MAIN
+#define VSX_REG_ATTR "wa"
#include "direct-move.h"
#include <math.h>
extern void abort (void);
+#ifndef VSX_REG_ATTR
+#define VSX_REG_ATTR "wa"
+#endif
+
void __attribute__((__noinline__))
copy (TYPE *a, TYPE *b)
{
load_vsx (TYPE *a, TYPE *b)
{
TYPE c = *a;
- __asm__ ("# vsx, reg = %x0" : "+wa" (c));
+ __asm__ ("# vsx, reg = %x0" : "+" VSX_REG_ATTR (c));
*b = c;
}
#endif
TYPE d;
__asm__ ("# gpr, reg = %0" : "+b" (c));
d = c;
- __asm__ ("# vsx, reg = %x0" : "+wa" (d));
+ __asm__ ("# vsx, reg = %x0" : "+" VSX_REG_ATTR (d));
*b = d;
}
#endif
{
TYPE c = *a;
TYPE d;
- __asm__ ("# vsx, reg = %x0" : "+wa" (c));
+ __asm__ ("# vsx, reg = %x0" : "+" VSX_REG_ATTR (c));
d = c;
__asm__ ("# gpr, reg = %0" : "+b" (d));
*b = d;
*p = d;
}
-/* { dg-final { scan-assembler-times "lxsspx" 2 } } */
-/* { dg-final { scan-assembler-times "lxsdx" 1 } } */
-/* { dg-final { scan-assembler-times "stxsspx" 1 } } */
-/* { dg-final { scan-assembler-times "stxsdx" 1 } } */
+/* { dg-final { scan-assembler "lxsspx" } } */
+/* { dg-final { scan-assembler "lxsdx" } } */
+/* { dg-final { scan-assembler "stxsspx" } } */
+/* { dg-final { scan-assembler "stxsdx" } } */
--- /dev/null
+/* { dg-do run { target { powerpc*-*-linux* } } } */
+/* { dg-options "-mlong-double-128" } */
+
+/* Check if adding a qNAN and a normal long double does not generate a
+ inexact exception. */
+
+#define _GNU_SOURCE
+#include <fenv.h>
+
+int main(void)
+{
+ double x = __builtin_nan ("");
+ long double y = 1.1L;
+
+ feenableexcept (FE_INEXACT);
+ feclearexcept (FE_ALL_EXCEPT);
+ x = x + y;
+ return fetestexcept(FE_INEXACT);
+}
/* { dg-options "-mcpu=power7 -O0 -m64" } */
long foo (void) { return 0; }
-
-/* { dg-final { scan-assembler-not "xxlor" } } */
-/* { dg-final { scan-assembler-not "stfd" } } */
-/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
-/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
-/* { dg-require-effective-target powerpc_vsx_ok } */
-/* { dg-options "-mcpu=power7 -O0 -m64" } */
-
-long foo (void) { return 0; }
-
-/* { dg-final { scan-assembler-not "xxlor" } } */
-/* { dg-final { scan-assembler-not "stfd" } } */
--- /dev/null
+! { dg-do compile }
+!
+! PR 59228: ICE with assumed type and ASYNCHRONOUS
+!
+! Contributed by Valery Weber <valeryweber@hotmail.com>
+
+ IMPLICIT NONE
+
+ interface
+ subroutine test(base)
+ TYPE(*), ASYNCHRONOUS :: base
+ end subroutine
+ end interface
+
+CONTAINS
+
+ SUBROUTINE foo ( data )
+ REAL, DIMENSION( : ), ASYNCHRONOUS :: data
+ CALL test ( data ) ! { dg-error "Rank mismatch in argument" }
+ END SUBROUTINE
+
+END
! { dg-final { scan-tree-dump-times "parm.\[0-9\]+.data = \\(void .\\) &\\(.yyy.\[0-9\]+\\)\\\[D.\[0-9\]+ \\* 4\\\];" 1 "original" } }
! { dg-final { scan-tree-dump-times "D.\[0-9\]+ = parm.\[0-9\]+.data;\[^;]+ptr\[1-4\] = D.\[0-9\]+;" 4 "original" } }
-! { dg-final { cleanup-tree-dump "optimized" } }
+! { dg-final { cleanup-tree-dump "original" } }
! { dg-options "-fno-range-check" }
! { dg-require-effective-target fortran_real_16 }
! { dg-require-effective-target fortran_integer_16 }
+! { dg-skip-if "" { "powerpc*le-*-*" } { "*" } { "" } }
! PR47293 NAN not correctly read
character(len=200) :: str
real(16) :: r
end subroutine test_PR34547_1
subroutine test_PR34547_2 ()
- print *, null () ! { dg-error "in data transfer statement requires MOLD" }
+ print *, null () ! { dg-error "Invalid context" }
end subroutine test_PR34547_2
subroutine test_PR34547_3 ()
subroutine test_PR34547_3 ()
integer, allocatable :: i(:)
- print *, NULL(i)
+ print *, NULL(i) ! { dg-error "Invalid context for NULL" }
end subroutine test_PR34547_3
--- /dev/null
+! PR middle-end/57393
+! { dg-do compile }
+! { dg-options "-g -O2 -ffast-math" }
+
+SUBROUTINE pr57393(nn,e,g,t0,t1,t2,t3,t4,t5,t6,t7,&
+ t8,t9,t10,t11,t12,t13,t14,t15,&
+ t16,t17,t18,t19,t20,t21,t22,t23,&
+ t24,t25,t26,t27,t28,t29,t30,&
+ t31,t32,t33,t34,t35,t36,t37,t38,&
+ t39,t40,t41,t42,t43,t44,t45,t46,t47)
+ IMPLICIT REAL*8 (t)
+ INTEGER, PARAMETER :: dp=8
+ REAL(kind=dp) :: e(nn)
+ DO ii=1,nn
+ t48 = 0.1955555555e2_dp * t1 * t2 + &
+ 0.6000000000e1_dp * t3 * t4 * t5
+ t49 = 0.1620000000e3_dp * t6 * t7 * t8 + &
+ 0.1080000000e3_dp * t6 * t9 * t5 - &
+ 0.6000000000e1_dp * t10 * t20 * t21 * t55 - &
+ 0.2400000000e2_dp * t10 * t11 * t12 - &
+ 0.1200000000e2_dp * t13 * t14 * t15
+ t50 = t49 + t16
+ t51 = (3 * t17 * t18 * t19) + &
+ (t22 * t23 * t19) + (t50 * t19) - &
+ 0.3333333336e0_dp * t24 * t25
+ t52 = 0.1555555556e1_dp * t26 * t27 * t12 + &
+ (t51 + t28 + t29 + t30) * &
+ 0.3125000000e0_dp * t31 * t32 * t33 * t34
+ t53 = -0.1000000001e1_dp * t35 * t36 * t5 - &
+ (t37 + t38 + t39 + t52) - &
+ 0.8333333340e-1_dp * t40 * t41 * t42
+ t54 = -0.1000000001e1_dp * t43 * t44 * t45 - &
+ t47 * (t46 + t53)
+ IF (g >= 3 .OR. g == -3) THEN
+ e(ii) = e(ii) + t54 * t0
+ END IF
+ END DO
+END SUBROUTINE pr57393
--- /dev/null
+! PR middle-end/57393
+! { dg-do compile }
+! { dg-options "-g -O2" }
+
+SUBROUTINE pr57393 ( a1, a2, a3, a4, a5, a6, a7 )
+ COMPLEX(kind=8), DIMENSION(:), INTENT(IN) :: a1
+ INTEGER, DIMENSION(:), INTENT(IN) :: a2, a3, a5, a6
+ COMPLEX(kind=8), DIMENSION(:), INTENT(INOUT) :: a4
+ a4(a6(1)+1:a6(1)+a5(1))=a1(a3(1)+1:a3(1)+a2(1))
+END SUBROUTINE pr57393
--- /dev/null
+! { dg-do run }
+!
+! PR fortran/57354
+!
+! Contributed by Vladimir Fuka <vladimir.fuka@gmail.com>
+!
+ type t
+ integer,allocatable :: i
+ end type
+
+ type(t) :: e
+ type(t), allocatable :: a(:)
+ integer :: chksum = 0
+
+ do i=1,3 ! Was 100 in original
+ e%i = i
+ chksum = chksum + i
+ if (.not.allocated(a)) then
+ a = [e]
+ else
+ call foo
+ end if
+ end do
+
+ if (sum ([(a(i)%i, i=1,size(a))]) .ne. chksum) call abort
+contains
+ subroutine foo
+ a = [a, e]
+ end subroutine
+end
--- /dev/null
+! { dg-do compile }
+!
+! PR 59143: [OOP] Bogus warning with array-valued type-bound procedure
+!
+! Contributed by Jürgen Reuter <juergen.reuter@desy.de>
+
+module phs_single
+
+ type :: phs_single_t
+ contains
+ procedure, nopass :: d1, d2
+ end type
+
+contains
+
+ subroutine evaluate (phs)
+ class(phs_single_t) :: phs
+ call func1 (phs%d1 ())
+ call func1 (phs%d2 (2))
+ end subroutine
+
+ subroutine func1 (p)
+ real :: p(2)
+ end subroutine
+
+ function d1 ()
+ real :: d1(2)
+ d1 = 1.
+ end function
+
+ function d2 (n)
+ real :: d2(n)
+ d2 = 1.
+ end function
+
+end module
+
+! { dg-final { cleanup-modules "phs_single" } }
--- /dev/null
+-- { dg-do compile }\r
+-- { dg-options "-O" }\r
+\r
+package body Opt29 is\r
+\r
+ procedure Proc (T : Rec) is\r
+ begin\r
+ if Derived2 (T.F2.all).Id = T.F1.Id then\r
+ raise Program_Error;\r
+ end if;\r
+ end;\r
+\r
+end Opt29;\r
--- /dev/null
+package Opt29 is\r
+\r
+ type Word is mod 2**16;\r
+\r
+ type PID is record\r
+ W1, W2: Word;\r
+ end record;\r
+\r
+ type Root1 is tagged record\r
+ Id: PID;\r
+ end record;\r
+ type Root1_Ptr is access all Root1'Class;\r
+\r
+ type Root2 is tagged null record;\r
+ type Root2_Ptr is access all Root2'class;\r
+\r
+ type Derived2 is new Root2 with record\r
+ Id: PID;\r
+ end record;\r
+\r
+ type Rec is record\r
+ F1: Root1_Ptr;\r
+ F2: Root2_Ptr;\r
+ end record;\r
+\r
+ procedure Proc (T : Rec);\r
+\r
+end Opt29;\r
--- /dev/null
+-- { dg-do run }
+-- { dg-options "-O" }
+
+procedure Opt30 is
+
+ function Id_I (I : Integer) return Integer is
+ begin
+ return I;
+ end;
+
+ A : array (Integer range -4..4) of Integer;
+
+begin
+ A := (-ID_I(4), -ID_I(3), -ID_I(2), -ID_I(1), ID_I(100),
+ ID_I(1), ID_I(2), ID_I(3), ID_I(4));
+ A(-4..0) := A(0..4);
+ if A /= (100, 1, 2, 3, 4, 1, 2, 3, 4) then
+ raise Program_Error;
+ end if;
+end;
if { $gccpath != "" } {
if { [file exists "${gccpath}/libsanitizer/asan/.libs/libasan.a"]
|| [file exists "${gccpath}/libsanitizer/asan/.libs/libasan.${shlib_ext}"] } {
+ append flags " -B${gccpath}/libsanitizer/ "
append flags " -B${gccpath}/libsanitizer/asan/ "
append flags " -L${gccpath}/libsanitizer/asan/.libs "
append ld_library_path ":${gccpath}/libsanitizer/asan/.libs"
|| [istarget mn10300-*-elf*]
|| [istarget moxie-*-elf*]
|| [istarget msp430-*-*]
+ || [istarget nds32*-*-elf]
|| [istarget picochip-*-*]
|| [istarget powerpc-*-eabi*]
|| [istarget powerpc-*-elf]
return $et_vect_floatuint_cvt_saved
}
+# Return 1 if the target supports #pragma omp declare simd, 0 otherwise.
+#
+# This won't change for different subtargets so cache the result.
+
+proc check_effective_target_vect_simd_clones { } {
+ global et_vect_simd_clones_saved
+
+ if [info exists et_vect_simd_clones_saved] {
+ verbose "check_effective_target_vect_simd_clones: using cached result" 2
+ } else {
+ set et_vect_simd_clones_saved 0
+ if { [istarget i?86-*-*] || [istarget x86_64-*-*] } {
+ # On i?86/x86_64 #pragma omp declare simd builds a sse2, avx and
+ # avx2 clone. Only the right clone for the specified arch will be
+ # chosen, but still we need to at least be able to assemble
+ # avx2.
+ if { [check_effective_target_avx2] } {
+ set et_vect_simd_clones_saved 1
+ }
+ }
+ }
+
+ verbose "check_effective_target_vect_simd_clones: returning $et_vect_simd_clones_saved" 2
+ return $et_vect_simd_clones_saved
+}
+
# Return 1 if this is a AArch64 target supporting big endian
proc check_effective_target_aarch64_big_endian { } {
return [check_no_compiler_messages aarch64_big_endian assembly {
} "-O2 -mavx" ]
}
+# Return 1 if avx2 instructions can be compiled.
+proc check_effective_target_avx2 { } {
+ return [check_no_compiler_messages avx2 object {
+ typedef long long __v4di __attribute__ ((__vector_size__ (32)));
+ __v4di
+ mm256_is32_andnotsi256 (__v4di __X, __v4di __Y)
+ {
+ return __builtin_ia32_andnotsi256 (__X, __Y);
+ }
+ } "-O0 -mavx2" ]
+}
+
# Return 1 if sse instructions can be compiled.
proc check_effective_target_sse { } {
return [check_no_compiler_messages sse object {
if { $gccpath != "" } {
if { [file exists "${gccpath}/libsanitizer/ubsan/.libs/libubsan.a"]
|| [file exists "${gccpath}/libsanitizer/ubsan/.libs/libubsan.${shlib_ext}"] } {
+ append flags " -B${gccpath}/libsanitizer/ "
append flags " -B${gccpath}/libsanitizer/ubsan/ "
append flags " -L${gccpath}/libsanitizer/ubsan/.libs"
append ld_library_path ":${gccpath}/libsanitizer/ubsan/.libs"
#include "function.h"
#include "toplev.h"
#include "expr.h"
-#include "basic-block.h"
#include "intl.h"
-#include "ggc.h"
#include "regs.h"
#include "timevar.h"
#include "diagnostic.h"
#include "alloc-pool.h"
#include "asan.h"
#include "tsan.h"
-#include "gimple.h"
#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "gimple.h"
#include "plugin.h"
#include "diagnostic-color.h"
#include "context.h"
"and -ftree-loop-linear)");
#endif
- if (flag_check_pointer_bounds)
- {
- if (targetm.chkp_bound_mode () == VOIDmode)
- error ("-fcheck-pointers is not supported for this target");
- }
-
/* One region RA really helps to decrease the code size. */
if (flag_ira_region == IRA_REGION_AUTODETECT)
flag_ira_region
#include "params.h"
#include "coverage.h"
#include "tree-pass.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "tree-cfg.h"
#include "coretypes.h"
#include "hash-table.h"
#include "tree.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "calls.h"
#include "function.h"
#include "tree-pretty-print.h"
#include "pointer-set.h"
#include "tree-affine.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimplify.h"
#include "flags.h"
#include "tree.h"
#include "stor-layout.h"
#include "gimple-pretty-print.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "basic-block.h"
#include "flags.h"
#include "function.h"
-#include "ggc.h"
#include "gimple-pretty-print.h"
+#include "pointer-set.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-fold.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimplify-me.h"
#include "cfgloop.h"
#include "tree-ssa-propagate.h"
#include "value-prof.h"
-#include "pointer-set.h"
#include "tree-inline.h"
#include "target.h"
#include "tree-ssa-live.h"
if (TREE_CODE (t) == BIT_FIELD_REF)
{
- if (!tree_fits_uhwi_p (TREE_OPERAND (t, 1))
- || !tree_fits_uhwi_p (TREE_OPERAND (t, 2)))
+ tree t0 = TREE_OPERAND (t, 0);
+ tree t1 = TREE_OPERAND (t, 1);
+ tree t2 = TREE_OPERAND (t, 2);
+ if (!tree_fits_uhwi_p (t1)
+ || !tree_fits_uhwi_p (t2))
{
error ("invalid position or size operand to BIT_FIELD_REF");
return t;
}
if (INTEGRAL_TYPE_P (TREE_TYPE (t))
&& (TYPE_PRECISION (TREE_TYPE (t))
- != tree_to_uhwi (TREE_OPERAND (t, 1))))
+ != tree_to_uhwi (t1)))
{
error ("integral result type precision does not match "
"field size of BIT_FIELD_REF");
else if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
&& TYPE_MODE (TREE_TYPE (t)) != BLKmode
&& (GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (t)))
- != tree_to_uhwi (TREE_OPERAND (t, 1))))
+ != tree_to_uhwi (t1)))
{
error ("mode precision of non-integral result does not "
"match field size of BIT_FIELD_REF");
return t;
}
+ if (!AGGREGATE_TYPE_P (TREE_TYPE (t0))
+ && (tree_to_uhwi (t1) + tree_to_uhwi (t2)
+ > tree_to_uhwi (TYPE_SIZE (TREE_TYPE (t0)))))
+ {
+ error ("position plus size exceeds size of referenced object in "
+ "BIT_FIELD_REF");
+ return t;
+ }
}
t = TREE_OPERAND (t, 0);
/* We cannot leave any operands allocated from the operand caches of
the current function. */
- free_stmt_operands (stmt);
+ free_stmt_operands (cfun, stmt);
push_cfun (dest_cfun);
update_stmt (stmt);
pop_cfun ();
#include "diagnostic-core.h"
#include "flags.h"
#include "function.h"
-#include "ggc.h"
#include "langhooks.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimplify.h"
#include "gimple-iterator.h"
#include "tree.h"
#include "tree-pretty-print.h"
#include "cfgloop.h"
-#include "gimple.h"
+#include "basic-block.h"
+#include "gimple-expr.h"
#include "tree-ssa-loop-ivopts.h"
#include "tree-ssa-loop-niter.h"
#include "tree-chrec.h"
#include "tree.h"
#include "stor-layout.h"
#include "flags.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimplify.h"
#include "gimple-iterator.h"
OMP_CLAUSE_SCHEDULE_DYNAMIC,
OMP_CLAUSE_SCHEDULE_GUIDED,
OMP_CLAUSE_SCHEDULE_AUTO,
- OMP_CLAUSE_SCHEDULE_RUNTIME
+ OMP_CLAUSE_SCHEDULE_RUNTIME,
+ OMP_CLAUSE_SCHEDULE_LAST
};
enum omp_clause_default_kind {
OMP_CLAUSE_DEFAULT_SHARED,
OMP_CLAUSE_DEFAULT_NONE,
OMP_CLAUSE_DEFAULT_PRIVATE,
- OMP_CLAUSE_DEFAULT_FIRSTPRIVATE
+ OMP_CLAUSE_DEFAULT_FIRSTPRIVATE,
+ OMP_CLAUSE_DEFAULT_LAST
};
/* There is a TYPE_QUAL value for each type qualifier. They can be
TI_FILEPTR_TYPE,
TI_POINTER_SIZED_TYPE,
- TI_POINTER_BOUNDS_TYPE,
-
TI_DFLOAT32_TYPE,
TI_DFLOAT64_TYPE,
TI_DFLOAT128_TYPE,
CALL_ALLOCA_FOR_VAR_P in
CALL_EXPR
+ OMP_CLAUSE_LINEAR_VARIABLE_STRIDE in
+ OMP_CLAUSE_LINEAR
+
side_effects_flag:
TREE_SIDE_EFFECTS in
{
OMP_CLAUSE_DEPEND_IN,
OMP_CLAUSE_DEPEND_OUT,
- OMP_CLAUSE_DEPEND_INOUT
+ OMP_CLAUSE_DEPEND_INOUT,
+ OMP_CLAUSE_DEPEND_LAST
};
enum omp_clause_map_kind
/* The following kind is an internal only map kind, used for pointer based
array sections. OMP_CLAUSE_SIZE for these is not the pointer size,
which is implicitly POINTER_SIZE / BITS_PER_UNIT, but the bias. */
- OMP_CLAUSE_MAP_POINTER
+ OMP_CLAUSE_MAP_POINTER,
+ OMP_CLAUSE_MAP_LAST
};
enum omp_clause_proc_bind_kind
OMP_CLAUSE_PROC_BIND_TRUE = 1,
OMP_CLAUSE_PROC_BIND_MASTER = 2,
OMP_CLAUSE_PROC_BIND_CLOSE = 3,
- OMP_CLAUSE_PROC_BIND_SPREAD = 4
+ OMP_CLAUSE_PROC_BIND_SPREAD = 4,
+ OMP_CLAUSE_PROC_BIND_LAST
};
struct GTY(()) tree_exp {
#include "tree.h"
#include "expr.h"
#include "gimple-pretty-print.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "tree-ssa-loop-niter.h"
#include "coretypes.h"
#include "tm.h"
#include "hashtab.h"
-#include "pointer-set.h"
#include "tree.h"
#include "stor-layout.h"
#include "tm_p.h"
#include "basic-block.h"
-#include "ggc.h"
#include "langhooks.h"
#include "flags.h"
#include "function.h"
#include "tree-pretty-print.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimple-walk.h"
#include "tree-dfa.h"
#include "tree-inline.h"
#include "tree-pass.h"
-#include "convert.h"
#include "params.h"
/* Build and maintain data flow information for trees. */
&& (unit_size = array_ref_element_size (exp),
TREE_CODE (unit_size) == INTEGER_CST))
{
- HOST_WIDE_INT hindex = TREE_INT_CST_LOW (index);
-
- hindex -= TREE_INT_CST_LOW (low_bound);
- hindex *= TREE_INT_CST_LOW (unit_size);
- byte_offset += hindex;
+ offset_int woffset
+ = offset_int::from (wi::sub (index, low_bound), SIGNED);
+ woffset *= wi::to_offset (unit_size);
+ byte_offset += woffset.to_shwi ();
}
else
return NULL_TREE;
diagnostic_info *diagnostic)
{
diagnostic_report_current_module (context, diagnostic->location);
- lang_hooks.print_error_function (context, input_filename, diagnostic);
+ lang_hooks.print_error_function (context, LOCATION_FILE (input_location),
+ diagnostic);
}
static void
#include "function.h"
#include "except.h"
#include "pointer-set.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "tree-inline.h"
#include "tree-pass.h"
#include "langhooks.h"
-#include "ggc.h"
#include "diagnostic-core.h"
#include "target.h"
#include "cfgloop.h"
#include "tree.h"
#include "stor-layout.h"
#include "varasm.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimple-walk.h"
#include "flags.h"
#include "basic-block.h"
#include "gimple-pretty-print.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-fold.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimplify.h"
#include "gimple-iterator.h"
gimple_stmt_iterator i;
for (i = gsi_start (stmts); !gsi_end_p (i); gsi_next (&i))
- free_stmt_operands (gsi_stmt (i));
+ free_stmt_operands (cfun, gsi_stmt (i));
}
free (bb->aux);
#include "basic-block.h"
#include "tree-iterator.h"
#include "intl.h"
+#include "pointer-set.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-fold.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimplify.h"
#include "gimple-iterator.h"
#include "tree-pretty-print.h"
#include "except.h"
#include "debug.h"
-#include "pointer-set.h"
#include "ipa-prop.h"
#include "value-prof.h"
#include "tree-pass.h"
case GIMPLE_CALL:
{
- tree decl = gimple_call_fndecl (stmt);
+ tree decl;
struct cgraph_node *node = NULL;
/* Do not special case builtins where we see the body.
This just confuse inliner. */
- if (!decl || !(node = cgraph_get_node (decl)) || node->definition)
+ if (gimple_call_internal_p (stmt))
+ return 0;
+ else if (!(decl = gimple_call_fndecl (stmt))
+ || !(node = cgraph_get_node (decl))
+ || node->definition)
;
/* For buitins that are likely expanded to nothing or
inlined do not account operand costs. */
gimple stmt = gsi_stmt (gsi);
if (is_gimple_call (stmt)
+ && !gimple_call_internal_p (stmt)
&& expand_call_inline (bb, stmt, id))
return true;
}
#include "basic-block.h"
#include "function.h"
#include "gimple-pretty-print.h"
+#include "hash-table.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "tree-dfa.h"
#include "tree-ssa.h"
#include "tree-inline.h"
-#include "hash-table.h"
#include "tree-pass.h"
#include "cfgloop.h"
#include "domwalk.h"
#include "system.h"
#include "coretypes.h"
#include "tree.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimplify-me.h"
#include "function.h"
#include "tree-dump.h"
#include "tree-inline.h"
+#include "pointer-set.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimplify.h"
#include "gimple-iterator.h"
#include "tree-cfg.h"
#include "expr.h" /* FIXME: For STACK_SAVEAREA_MODE and SAVE_NONLOCAL. */
#include "langhooks.h"
-#include "pointer-set.h"
#include "gimple-low.h"
#include "function.h"
#include "basic-block.h"
#include "tree-pretty-print.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimple-walk.h"
#include "diagnostic-core.h"
#include "gimple-pretty-print.h"
#include "bitmap.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-fold.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimple-ssa.h"
the subobject (innermost array or field with address taken).
object_sizes[2] is lower bound for number of bytes till the end of
the object and object_sizes[3] lower bound for subobject. */
-static unsigned HOST_WIDE_INT *object_sizes[4];
+static vec<unsigned HOST_WIDE_INT> object_sizes[4];
/* Bitmaps what object sizes have been computed already. */
static bitmap computed[4];
if (TREE_CODE (ptr) == SSA_NAME
&& POINTER_TYPE_P (TREE_TYPE (ptr))
- && object_sizes[object_size_type] != NULL)
+ && computed[object_size_type] != NULL)
{
if (!bitmap_bit_p (computed[object_size_type], SSA_NAME_VERSION (ptr)))
{
bitmap_iterator bi;
unsigned int i;
+ if (num_ssa_names > object_sizes[object_size_type].length ())
+ object_sizes[object_size_type].safe_grow (num_ssa_names);
if (dump_file)
{
fprintf (dump_file, "Computing %s %sobject size for ",
{
int object_size_type;
- if (object_sizes[0])
+ if (computed[0])
return;
for (object_size_type = 0; object_size_type <= 3; object_size_type++)
{
- object_sizes[object_size_type] = XNEWVEC (unsigned HOST_WIDE_INT, num_ssa_names);
+ object_sizes[object_size_type].safe_grow (num_ssa_names);
computed[object_size_type] = BITMAP_ALLOC (NULL);
}
for (object_size_type = 0; object_size_type <= 3; object_size_type++)
{
- free (object_sizes[object_size_type]);
+ object_sizes[object_size_type].release ();
BITMAP_FREE (computed[object_size_type]);
- object_sizes[object_size_type] = NULL;
}
}
#include "tm.h"
#include "tree.h"
#include "stor-layout.h"
-#include "ggc.h"
#include "basic-block.h"
#include "gimple-pretty-print.h"
#include "bitmap.h"
#include "sbitmap.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "system.h"
#include "coretypes.h"
#include "tree.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimplify.h"
#include "gimple-iterator.h"
extern ipa_opt_pass_d *make_pass_ipa_pure_const (gcc::context *ctxt);
extern simple_ipa_opt_pass *make_pass_ipa_pta (gcc::context *ctxt);
extern simple_ipa_opt_pass *make_pass_ipa_tm (gcc::context *ctxt);
+extern simple_ipa_opt_pass *make_pass_omp_simd_clone (gcc::context *ctxt);
extern ipa_opt_pass_d *make_pass_ipa_profile (gcc::context *ctxt);
extern ipa_opt_pass_d *make_pass_ipa_cdtor_merge (gcc::context *ctxt);
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
-#include "ggc.h"
#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "tree.h"
#include "tm_p.h"
#include "cfgloop.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimplify.h"
#include "gimple-iterator.h"
#include "expr.h"
#include "tree-dfa.h"
#include "tree-ssa.h"
-#include "ggc.h"
#include "tree-data-ref.h"
#include "tree-scalar-evolution.h"
#include "tree-chrec.h"
#include "expr.h"
#include "tree-pretty-print.h"
#include "hashtab.h"
-#include "gimple.h"
+#include "pointer-set.h"
+#include "gimple-expr.h"
#include "cgraph.h"
#include "langhooks.h"
#include "tree-iterator.h"
break;
case VOID_TYPE:
- case POINTER_BOUNDS_TYPE:
case INTEGER_TYPE:
case REAL_TYPE:
case FIXED_POINT_TYPE:
#include "diagnostic-core.h"
#include "coverage.h"
#include "tree.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "varasm.h"
#include "tree-nested.h"
#include "coretypes.h"
#include "tree.h"
#include "expr.h"
-#include "hash-table.h"
#include "gimple-pretty-print.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimplify.h"
#include "gimple-iterator.h"
#include "alloc-pool.h"
#include "tm.h"
#include "tree.h"
+#include "pointer-set.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "stor-layout.h"
#include "gimplify.h"
adj.base_index = get_param_index (parm, parms);
adj.base = parm;
if (!repr)
- adj.copy_param = 1;
+ adj.op = IPA_PARM_OP_COPY;
else
- adj.remove_param = 1;
+ adj.op = IPA_PARM_OP_REMOVE;
+ adj.arg_prefix = "ISRA";
adjustments.quick_push (adj);
}
else
adj.by_ref = (POINTER_TYPE_P (TREE_TYPE (repr->base))
&& (repr->grp_maybe_modified
|| repr->grp_not_necessarilly_dereferenced));
+ adj.arg_prefix = "ISRA";
adjustments.quick_push (adj);
}
}
struct ipa_parm_adjustment *adj;
adj = &adjustments[i];
- if (!adj->copy_param && adj->base == base)
+ if (adj->op != IPA_PARM_OP_COPY && adj->base == base)
return adj;
}
return true;
}
-/* If the expression *EXPR should be replaced by a reduction of a parameter, do
- so. ADJUSTMENTS is a pointer to a vector of adjustments. CONVERT
- specifies whether the function should care about type incompatibility the
- current and new expressions. If it is false, the function will leave
- incompatibility issues to the caller. Return true iff the expression
- was modified. */
-
-static bool
-sra_ipa_modify_expr (tree *expr, bool convert,
- ipa_parm_adjustment_vec adjustments)
-{
- int i, len;
- struct ipa_parm_adjustment *adj, *cand = NULL;
- HOST_WIDE_INT offset, size, max_size;
- tree base, src;
-
- len = adjustments.length ();
-
- if (TREE_CODE (*expr) == BIT_FIELD_REF
- || TREE_CODE (*expr) == IMAGPART_EXPR
- || TREE_CODE (*expr) == REALPART_EXPR)
- {
- expr = &TREE_OPERAND (*expr, 0);
- convert = true;
- }
-
- base = get_ref_base_and_extent (*expr, &offset, &size, &max_size);
- if (!base || size == -1 || max_size == -1)
- return false;
-
- if (TREE_CODE (base) == MEM_REF)
- {
- offset += mem_ref_offset (base).to_short_addr () * BITS_PER_UNIT;
- base = TREE_OPERAND (base, 0);
- }
-
- base = get_ssa_base_param (base);
- if (!base || TREE_CODE (base) != PARM_DECL)
- return false;
-
- for (i = 0; i < len; i++)
- {
- adj = &adjustments[i];
-
- if (adj->base == base
- && (adj->offset == offset || adj->remove_param))
- {
- cand = adj;
- break;
- }
- }
- if (!cand || cand->copy_param || cand->remove_param)
- return false;
-
- if (cand->by_ref)
- src = build_simple_mem_ref (cand->reduction);
- else
- src = cand->reduction;
-
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "About to replace expr ");
- print_generic_expr (dump_file, *expr, 0);
- fprintf (dump_file, " with ");
- print_generic_expr (dump_file, src, 0);
- fprintf (dump_file, "\n");
- }
-
- if (convert && !useless_type_conversion_p (TREE_TYPE (*expr), cand->type))
- {
- tree vce = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (*expr), src);
- *expr = vce;
- }
- else
- *expr = src;
- return true;
-}
-
/* If the statement pointed to by STMT_PTR contains any expressions that need
to replaced with a different one as noted by ADJUSTMENTS, do so. Handle any
potential type incompatibilities (GSI is used to accommodate conversion
rhs_p = gimple_assign_rhs1_ptr (stmt);
lhs_p = gimple_assign_lhs_ptr (stmt);
- any = sra_ipa_modify_expr (rhs_p, false, adjustments);
- any |= sra_ipa_modify_expr (lhs_p, false, adjustments);
+ any = ipa_modify_expr (rhs_p, false, adjustments);
+ any |= ipa_modify_expr (lhs_p, false, adjustments);
if (any)
{
tree new_rhs = NULL_TREE;
/* Traverse the function body and all modifications as described in
ADJUSTMENTS. Return true iff the CFG has been changed. */
-static bool
+bool
ipa_sra_modify_function_body (ipa_parm_adjustment_vec adjustments)
{
bool cfg_changed = false;
case GIMPLE_RETURN:
t = gimple_return_retval_ptr (stmt);
if (*t != NULL_TREE)
- modified |= sra_ipa_modify_expr (t, true, adjustments);
+ modified |= ipa_modify_expr (t, true, adjustments);
break;
case GIMPLE_ASSIGN:
for (i = 0; i < gimple_call_num_args (stmt); i++)
{
t = gimple_call_arg_ptr (stmt, i);
- modified |= sra_ipa_modify_expr (t, true, adjustments);
+ modified |= ipa_modify_expr (t, true, adjustments);
}
if (gimple_call_lhs (stmt))
{
t = gimple_call_lhs_ptr (stmt);
- modified |= sra_ipa_modify_expr (t, false, adjustments);
+ modified |= ipa_modify_expr (t, false, adjustments);
modified |= replace_removed_params_ssa_names (stmt,
adjustments);
}
for (i = 0; i < gimple_asm_ninputs (stmt); i++)
{
t = &TREE_VALUE (gimple_asm_input_op (stmt, i));
- modified |= sra_ipa_modify_expr (t, true, adjustments);
+ modified |= ipa_modify_expr (t, true, adjustments);
}
for (i = 0; i < gimple_asm_noutputs (stmt); i++)
{
t = &TREE_VALUE (gimple_asm_output_op (stmt, i));
- modified |= sra_ipa_modify_expr (t, false, adjustments);
+ modified |= ipa_modify_expr (t, false, adjustments);
}
break;
use_operand_p use_p;
adj = &adjustments[i];
- if (adj->copy_param || !is_gimple_reg (adj->base))
+ if (adj->op == IPA_PARM_OP_COPY || !is_gimple_reg (adj->base))
continue;
name = ssa_default_def (cfun, adj->base);
vexpr = NULL;
redirect_callers.release ();
push_cfun (DECL_STRUCT_FUNCTION (new_node->decl));
- ipa_modify_formal_parameters (current_function_decl, adjustments, "ISRA");
+ ipa_modify_formal_parameters (current_function_decl, adjustments);
cfg_changed = ipa_sra_modify_function_body (adjustments);
sra_ipa_reset_debug_stmts (adjustments);
convert_callers (new_node, node->decl, adjustments);
#include "tm_p.h"
#include "basic-block.h"
#include "tree-pretty-print.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimplify-me.h"
#include "rtl.h"
#include "recog.h"
#include "expr.h"
-#include "ggc.h"
#include "target.h"
#include "expmed.h"
#include "tree-ssa-address.h"
#include "target.h"
#include "basic-block.h"
#include "timevar.h" /* for TV_ALIAS_STMT_WALK */
-#include "ggc.h"
#include "langhooks.h"
#include "flags.h"
#include "function.h"
#include "tree-pretty-print.h"
#include "dumpfile.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-ssa.h"
#include "stringpool.h"
#include "tree-dfa.h"
#include "tree-inline.h"
#include "params.h"
-#include "vec.h"
-#include "pointer-set.h"
#include "alloc-pool.h"
#include "tree-ssa-alias.h"
#include "ipa-reference.h"
#include "basic-block.h"
#include "function.h"
#include "gimple-pretty-print.h"
+#include "hash-table.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-fold.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimplify.h"
#include "gimple-iterator.h"
#include "diagnostic-core.h"
#include "dbgcnt.h"
#include "params.h"
-#include "hash-table.h"
#include "wide-int-print.h"
#include "tree-pretty-print.h"
#include "bitmap.h"
#include "dumpfile.h"
+#include "hash-table.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "ssa-iterators.h"
#include "stringpool.h"
#include "tree-ssanames.h"
-#include "hash-table.h"
#include "tree-ssa-live.h"
#include "tree-ssa-coalesce.h"
#include "diagnostic-core.h"
#include "basic-block.h"
#include "function.h"
#include "gimple-pretty-print.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "flags.h"
-#include "basic-block.h"
#include "function.h"
#include "tree-pretty-print.h"
#include "bitmap.h"
#include "calls.h"
#include "gimple-pretty-print.h"
#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimplify.h"
#include "gimple-iterator.h"
stats.total++;
/* We can mark a call to free as not necessary if the
- defining statement of its argument is an allocation
- function and that is not necessary itself. */
- if (gimple_call_builtin_p (stmt, BUILT_IN_FREE))
+ defining statement of its argument is not necessary
+ (and thus is getting removed). */
+ if (gimple_plf (stmt, STMT_NECESSARY)
+ && gimple_call_builtin_p (stmt, BUILT_IN_FREE))
{
tree ptr = gimple_call_arg (stmt, 0);
- tree callee2;
- gimple def_stmt;
- if (TREE_CODE (ptr) != SSA_NAME)
- continue;
- def_stmt = SSA_NAME_DEF_STMT (ptr);
- if (!is_gimple_call (def_stmt)
- || gimple_plf (def_stmt, STMT_NECESSARY))
- continue;
- callee2 = gimple_call_fndecl (def_stmt);
- if (callee2 == NULL_TREE
- || DECL_BUILT_IN_CLASS (callee2) != BUILT_IN_NORMAL
- || (DECL_FUNCTION_CODE (callee2) != BUILT_IN_MALLOC
- && DECL_FUNCTION_CODE (callee2) != BUILT_IN_CALLOC))
- continue;
- gimple_set_plf (stmt, STMT_NECESSARY, false);
+ if (TREE_CODE (ptr) == SSA_NAME)
+ {
+ gimple def_stmt = SSA_NAME_DEF_STMT (ptr);
+ if (!gimple_nop_p (def_stmt)
+ && !gimple_plf (def_stmt, STMT_NECESSARY))
+ gimple_set_plf (stmt, STMT_NECESSARY, false);
+ }
}
/* If GSI is not necessary then remove it. */
#include "cfgloop.h"
#include "function.h"
#include "gimple-pretty-print.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-fold.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
-#include "ggc.h"
#include "tree.h"
#include "tm_p.h"
#include "basic-block.h"
#include "gimple-pretty-print.h"
#include "bitmap.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "tm_p.h"
#include "basic-block.h"
#include "gimple-pretty-print.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-fold.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimplify.h"
#include "gimple-iterator.h"
{
tree outer_type = TREE_TYPE (gimple_assign_lhs (stmt));
tree inner_type = TREE_TYPE (gimple_assign_rhs1 (stmt));
- if (INTEGRAL_TYPE_P (outer_type)
+ if (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
+ && INTEGRAL_TYPE_P (outer_type)
&& INTEGRAL_TYPE_P (inner_type)
&& (TYPE_PRECISION (outer_type)
<= TYPE_PRECISION (inner_type)))
#include "stor-layout.h"
#include "basic-block.h"
#include "tree-pretty-print.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-fold.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimplify-me.h"
#include "gimple-pretty-print.h"
#include "bitmap.h"
#include "sbitmap.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "tree.h"
#include "tm_p.h"
#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "tm_p.h"
#include "basic-block.h"
#include "gimple-pretty-print.h"
+#include "pointer-set.h"
+#include "hash-table.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimplify.h"
#include "gimple-iterator.h"
#include "params.h"
#include "tree-pass.h"
#include "flags.h"
-#include "hash-table.h"
#include "tree-affine.h"
-#include "pointer-set.h"
#include "tree-ssa-propagate.h"
#include "trans-mem.h"
#include "tm_p.h"
#include "basic-block.h"
#include "gimple-pretty-print.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-fold.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "tm_p.h"
#include "basic-block.h"
#include "gimple-pretty-print.h"
+#include "pointer-set.h"
+#include "hash-table.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimplify.h"
#include "gimple-iterator.h"
#include "tree-ssa.h"
#include "cfgloop.h"
#include "tree-pass.h"
-#include "ggc.h"
#include "insn-config.h"
-#include "pointer-set.h"
-#include "hash-table.h"
#include "tree-chrec.h"
#include "tree-scalar-evolution.h"
#include "cfgloop.h"
#include "tree.h"
#include "tm_p.h"
#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimplify.h"
#include "gimple-iterator.h"
#include "basic-block.h"
#include "gimple-pretty-print.h"
#include "intl.h"
+#include "pointer-set.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimplify.h"
#include "gimple-iterator.h"
#include "tree-ssa-loop.h"
#include "dumpfile.h"
#include "cfgloop.h"
-#include "ggc.h"
#include "tree-chrec.h"
#include "tree-scalar-evolution.h"
#include "tree-data-ref.h"
return NULL;
}
- if (gimple_code (stmt) != GIMPLE_ASSIGN)
+ if (gimple_code (stmt) != GIMPLE_ASSIGN
+ || gimple_assign_rhs_class (stmt) == GIMPLE_TERNARY_RHS)
return NULL;
code = gimple_assign_rhs_code (stmt);
{
gimple stmt;
- gcc_assert (is_gimple_min_invariant (base));
+ gcc_checking_assert (is_gimple_min_invariant (base));
if (!x)
return base;
if (gimple_code (stmt) == GIMPLE_PHI)
return base;
- gcc_assert (is_gimple_assign (stmt));
+ gcc_checking_assert (is_gimple_assign (stmt));
/* STMT must be either an assignment of a single SSA name or an
expression involving an SSA name and a constant. Try to fold that
#include "tm_p.h"
#include "basic-block.h"
#include "tree-pretty-print.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimplify.h"
#include "gimple-iterator.h"
#include "tree.h"
#include "tm_p.h"
#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimplify.h"
#include "gimple-ssa.h"
#include "tree.h"
#include "tm_p.h"
#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "tree-ssa-loop-ivopts.h"
#include "tm.h"
#include "flags.h"
#include "tree.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-fold.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimplify-me.h"
#include "tree-ssa.h"
#include "tree-pass.h"
#include "alloc-pool.h"
-#include "basic-block.h"
#include "target.h"
#include "gimple-pretty-print.h"
#include "function.h"
#include "gimple-pretty-print.h"
#include "bitmap.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-ssa.h"
#include "tree-phinodes.h"
#include "tree-inline.h"
#include "timevar.h"
#include "dumpfile.h"
-#include "ggc.h"
#include "timevar.h"
#include "langhooks.h"
#include "diagnostic-core.h"
VUSE for 'b'. */
#define opf_no_vops (1 << 1)
-/* Operand is an implicit reference. This is used to distinguish
- explicit assignments in the form of MODIFY_EXPR from
- clobbering sites like function calls or ASM_EXPRs. */
-#define opf_implicit (1 << 2)
-
/* Operand is in a place where address-taken does not imply addressable. */
#define opf_non_addressable (1 << 3)
/* Operand is in a place where opf_non_addressable does not apply. */
#define opf_not_non_addressable (1 << 4)
+/* Operand is having its address taken. */
+#define opf_address_taken (1 << 5)
+
/* Array for building all the use operands. */
static vec<tree> build_uses;
compilations of multiple functions. */
static bitmap_obstack operands_bitmap_obstack;
-static void get_expr_operands (gimple, tree *, int);
+static void get_expr_operands (struct function *, gimple, tree *, int);
/* Number of functions with initialized ssa_operands. */
static int n_initialized = 0;
/* Dispose of anything required by the operand routines. */
void
-fini_ssa_operands (void)
+fini_ssa_operands (struct function *fn)
{
struct ssa_operand_memory_d *ptr;
build_vuse = NULL_TREE;
}
- gimple_ssa_operands (cfun)->free_uses = NULL;
+ gimple_ssa_operands (fn)->free_uses = NULL;
- while ((ptr = gimple_ssa_operands (cfun)->operand_memory) != NULL)
+ while ((ptr = gimple_ssa_operands (fn)->operand_memory) != NULL)
{
- gimple_ssa_operands (cfun)->operand_memory
- = gimple_ssa_operands (cfun)->operand_memory->next;
+ gimple_ssa_operands (fn)->operand_memory
+ = gimple_ssa_operands (fn)->operand_memory->next;
ggc_free (ptr);
}
- gimple_ssa_operands (cfun)->ops_active = false;
+ gimple_ssa_operands (fn)->ops_active = false;
if (!n_initialized)
bitmap_obstack_release (&operands_bitmap_obstack);
- cfun->gimple_df->vop = NULL_TREE;
+ fn->gimple_df->vop = NULL_TREE;
}
/* Return memory for an operand of size SIZE. */
static inline void *
-ssa_operand_alloc (unsigned size)
+ssa_operand_alloc (struct function *fn, unsigned size)
{
char *ptr;
gcc_assert (size == sizeof (struct use_optype_d));
- if (gimple_ssa_operands (cfun)->operand_memory_index + size
- >= gimple_ssa_operands (cfun)->ssa_operand_mem_size)
+ if (gimple_ssa_operands (fn)->operand_memory_index + size
+ >= gimple_ssa_operands (fn)->ssa_operand_mem_size)
{
struct ssa_operand_memory_d *ptr;
- switch (gimple_ssa_operands (cfun)->ssa_operand_mem_size)
+ switch (gimple_ssa_operands (fn)->ssa_operand_mem_size)
{
case OP_SIZE_INIT:
- gimple_ssa_operands (cfun)->ssa_operand_mem_size = OP_SIZE_1;
+ gimple_ssa_operands (fn)->ssa_operand_mem_size = OP_SIZE_1;
break;
case OP_SIZE_1:
- gimple_ssa_operands (cfun)->ssa_operand_mem_size = OP_SIZE_2;
+ gimple_ssa_operands (fn)->ssa_operand_mem_size = OP_SIZE_2;
break;
case OP_SIZE_2:
case OP_SIZE_3:
- gimple_ssa_operands (cfun)->ssa_operand_mem_size = OP_SIZE_3;
+ gimple_ssa_operands (fn)->ssa_operand_mem_size = OP_SIZE_3;
break;
default:
gcc_unreachable ();
ptr = ggc_alloc_ssa_operand_memory_d (sizeof (void *)
- + gimple_ssa_operands (cfun)->ssa_operand_mem_size);
+ + gimple_ssa_operands (fn)->ssa_operand_mem_size);
- ptr->next = gimple_ssa_operands (cfun)->operand_memory;
- gimple_ssa_operands (cfun)->operand_memory = ptr;
- gimple_ssa_operands (cfun)->operand_memory_index = 0;
+ ptr->next = gimple_ssa_operands (fn)->operand_memory;
+ gimple_ssa_operands (fn)->operand_memory = ptr;
+ gimple_ssa_operands (fn)->operand_memory_index = 0;
}
- ptr = &(gimple_ssa_operands (cfun)->operand_memory
- ->mem[gimple_ssa_operands (cfun)->operand_memory_index]);
- gimple_ssa_operands (cfun)->operand_memory_index += size;
+ ptr = &(gimple_ssa_operands (fn)->operand_memory
+ ->mem[gimple_ssa_operands (fn)->operand_memory_index]);
+ gimple_ssa_operands (fn)->operand_memory_index += size;
return ptr;
}
/* Allocate a USE operand. */
static inline struct use_optype_d *
-alloc_use (void)
+alloc_use (struct function *fn)
{
struct use_optype_d *ret;
- if (gimple_ssa_operands (cfun)->free_uses)
+ if (gimple_ssa_operands (fn)->free_uses)
{
- ret = gimple_ssa_operands (cfun)->free_uses;
- gimple_ssa_operands (cfun)->free_uses
- = gimple_ssa_operands (cfun)->free_uses->next;
+ ret = gimple_ssa_operands (fn)->free_uses;
+ gimple_ssa_operands (fn)->free_uses
+ = gimple_ssa_operands (fn)->free_uses->next;
}
else
ret = (struct use_optype_d *)
- ssa_operand_alloc (sizeof (struct use_optype_d));
+ ssa_operand_alloc (fn, sizeof (struct use_optype_d));
return ret;
}
/* Adds OP to the list of uses of statement STMT after LAST. */
static inline use_optype_p
-add_use_op (gimple stmt, tree *op, use_optype_p last)
+add_use_op (struct function *fn, gimple stmt, tree *op, use_optype_p last)
{
use_optype_p new_use;
- new_use = alloc_use ();
+ new_use = alloc_use (fn);
USE_OP_PTR (new_use)->use = op;
link_imm_use_stmt (USE_OP_PTR (new_use), *op, stmt);
last->next = new_use;
TODO -- Make build_defs vec of tree *. */
static inline void
-finalize_ssa_defs (gimple stmt)
+finalize_ssa_defs (struct function *fn, gimple stmt)
{
/* Pre-pend the vdef we may have built. */
if (build_vdef != NULL_TREE)
if (TREE_CODE (gimple_vdef (stmt)) == SSA_NAME)
{
unlink_stmt_vdef (stmt);
- release_ssa_name (gimple_vdef (stmt));
+ release_ssa_name_fn (fn, gimple_vdef (stmt));
}
gimple_set_vdef (stmt, NULL_TREE);
}
if (gimple_vdef (stmt)
&& TREE_CODE (gimple_vdef (stmt)) != SSA_NAME)
{
- cfun->gimple_df->rename_vops = 1;
- cfun->gimple_df->ssa_renaming_needed = 1;
+ fn->gimple_df->rename_vops = 1;
+ fn->gimple_df->ssa_renaming_needed = 1;
}
}
TODO -- Make build_uses vec of tree *. */
static inline void
-finalize_ssa_uses (gimple stmt)
+finalize_ssa_uses (struct function *fn, gimple stmt)
{
unsigned new_i;
struct use_optype_d new_list;
{
for (ptr = old_ops; ptr; ptr = ptr->next)
delink_imm_use (USE_OP_PTR (ptr));
- old_ops->next = gimple_ssa_operands (cfun)->free_uses;
- gimple_ssa_operands (cfun)->free_uses = old_ops;
+ old_ops->next = gimple_ssa_operands (fn)->free_uses;
+ gimple_ssa_operands (fn)->free_uses = old_ops;
}
/* If we added a VUSE, make sure to set the operand if it is not already
if (build_vuse != NULL_TREE
&& gimple_vuse (stmt) == NULL_TREE)
{
- gimple_set_vuse (stmt, gimple_vop (cfun));
- cfun->gimple_df->rename_vops = 1;
- cfun->gimple_df->ssa_renaming_needed = 1;
+ gimple_set_vuse (stmt, gimple_vop (fn));
+ fn->gimple_df->rename_vops = 1;
+ fn->gimple_df->ssa_renaming_needed = 1;
}
/* Now create nodes for all the new nodes. */
for (new_i = 0; new_i < build_uses.length (); new_i++)
{
tree *op = (tree *) build_uses[new_i];
- last = add_use_op (stmt, op, last);
+ last = add_use_op (fn, stmt, op, last);
}
/* Now set the stmt's operands. */
/* Finalize all the build vectors, fill the new ones into INFO. */
static inline void
-finalize_ssa_stmt_operands (gimple stmt)
+finalize_ssa_stmt_operands (struct function *fn, gimple stmt)
{
- finalize_ssa_defs (stmt);
- finalize_ssa_uses (stmt);
+ finalize_ssa_defs (fn, stmt);
+ finalize_ssa_uses (fn, stmt);
cleanup_build_arrays ();
}
/* Add virtual operands for STMT. FLAGS is as in get_expr_operands. */
static void
-add_virtual_operand (gimple stmt ATTRIBUTE_UNUSED, int flags)
+add_virtual_operand (struct function *fn,
+ gimple stmt ATTRIBUTE_UNUSED, int flags)
{
/* Add virtual operands to the stmt, unless the caller has specifically
requested not to do that (used when adding operands inside an
gcc_assert (!is_gimple_debug (stmt));
if (flags & opf_def)
- append_vdef (gimple_vop (cfun));
+ append_vdef (gimple_vop (fn));
else
- append_vuse (gimple_vop (cfun));
+ append_vuse (gimple_vop (fn));
}
added to virtual operands. */
static void
-add_stmt_operand (tree *var_p, gimple stmt, int flags)
+add_stmt_operand (struct function *fn, tree *var_p, gimple stmt, int flags)
{
tree var = *var_p;
else
append_use (var_p);
if (DECL_P (*var_p))
- cfun->gimple_df->ssa_renaming_needed = 1;
+ fn->gimple_df->ssa_renaming_needed = 1;
}
else
{
gimple_set_has_volatile_ops (stmt, true);
/* The variable is a memory access. Add virtual operands. */
- add_virtual_operand (stmt, flags);
+ add_virtual_operand (fn, stmt, flags);
}
}
FLAGS is as in get_expr_operands. */
static void
-get_indirect_ref_operands (gimple stmt, tree expr, int flags)
+get_mem_ref_operands (struct function *fn,
+ gimple stmt, tree expr, int flags)
{
tree *pptr = &TREE_OPERAND (expr, 0);
gimple_set_has_volatile_ops (stmt, true);
/* Add the VOP. */
- add_virtual_operand (stmt, flags);
+ add_virtual_operand (fn, stmt, flags);
/* If requested, add a USE operand for the base pointer. */
- get_expr_operands (stmt, pptr,
+ get_expr_operands (fn, stmt, pptr,
opf_non_addressable | opf_use
| (flags & (opf_no_vops|opf_not_non_addressable)));
}
/* A subroutine of get_expr_operands to handle TARGET_MEM_REF. */
static void
-get_tmr_operands (gimple stmt, tree expr, int flags)
+get_tmr_operands (struct function *fn, gimple stmt, tree expr, int flags)
{
if (!(flags & opf_no_vops)
&& TREE_THIS_VOLATILE (expr))
gimple_set_has_volatile_ops (stmt, true);
/* First record the real operands. */
- get_expr_operands (stmt, &TMR_BASE (expr), opf_use | (flags & opf_no_vops));
- get_expr_operands (stmt, &TMR_INDEX (expr), opf_use | (flags & opf_no_vops));
- get_expr_operands (stmt, &TMR_INDEX2 (expr), opf_use | (flags & opf_no_vops));
-
- add_virtual_operand (stmt, flags);
+ get_expr_operands (fn, stmt,
+ &TMR_BASE (expr), opf_use | (flags & opf_no_vops));
+ get_expr_operands (fn, stmt,
+ &TMR_INDEX (expr), opf_use | (flags & opf_no_vops));
+ get_expr_operands (fn, stmt,
+ &TMR_INDEX2 (expr), opf_use | (flags & opf_no_vops));
+
+ add_virtual_operand (fn, stmt, flags);
}
escape, add them to the VDEF/VUSE lists for it. */
static void
-maybe_add_call_vops (gimple stmt)
+maybe_add_call_vops (struct function *fn, gimple stmt)
{
int call_flags = gimple_call_flags (stmt);
A 'noreturn' function might, but since we don't return anyway
there is no point in recording that. */
if (!(call_flags & (ECF_PURE | ECF_CONST | ECF_NORETURN)))
- add_virtual_operand (stmt, opf_def);
+ add_virtual_operand (fn, stmt, opf_def);
else if (!(call_flags & ECF_CONST))
- add_virtual_operand (stmt, opf_use);
+ add_virtual_operand (fn, stmt, opf_use);
}
}
/* Scan operands in the ASM_EXPR stmt referred to in INFO. */
static void
-get_asm_expr_operands (gimple stmt)
+get_asm_stmt_operands (struct function *fn, gimple stmt)
{
size_t i, noutputs;
const char **oconstraints;
if (!allows_reg && allows_mem)
mark_address_taken (TREE_VALUE (link));
- get_expr_operands (stmt, &TREE_VALUE (link), opf_def | opf_not_non_addressable);
+ get_expr_operands (fn, stmt,
+ &TREE_VALUE (link), opf_def | opf_not_non_addressable);
}
/* Gather all input operands. */
if (!allows_reg && allows_mem)
mark_address_taken (TREE_VALUE (link));
- get_expr_operands (stmt, &TREE_VALUE (link), opf_not_non_addressable);
+ get_expr_operands (fn, stmt, &TREE_VALUE (link), opf_not_non_addressable);
}
/* Clobber all memory and addressable symbols for asm ("" : : : "memory"); */
if (gimple_asm_clobbers_memory_p (stmt))
- add_virtual_operand (stmt, opf_def);
+ add_virtual_operand (fn, stmt, opf_def);
}
interpret the operands found. */
static void
-get_expr_operands (gimple stmt, tree *expr_p, int flags)
+get_expr_operands (struct function *fn, gimple stmt, tree *expr_p, int flags)
{
enum tree_code code;
enum tree_code_class codeclass;
&& !is_gimple_debug (stmt))
mark_address_taken (TREE_OPERAND (expr, 0));
- /* If the address is invariant, there may be no interesting
- variable references inside. */
- if (is_gimple_min_invariant (expr))
- return;
-
/* Otherwise, there may be variables referenced inside but there
should be no VUSEs created, since the referenced objects are
not really accessed. The only operands that we should find
here are ARRAY_REF indices which will always be real operands
(GIMPLE does not allow non-registers as array indices). */
flags |= opf_no_vops;
- get_expr_operands (stmt, &TREE_OPERAND (expr, 0),
- flags | opf_not_non_addressable);
+ get_expr_operands (fn, stmt, &TREE_OPERAND (expr, 0),
+ flags | opf_not_non_addressable | opf_address_taken);
return;
case SSA_NAME:
case VAR_DECL:
case PARM_DECL:
case RESULT_DECL:
- add_stmt_operand (expr_p, stmt, flags);
+ if (!(flags & opf_address_taken))
+ add_stmt_operand (fn, expr_p, stmt, flags);
return;
case DEBUG_EXPR_DECL:
return;
case MEM_REF:
- get_indirect_ref_operands (stmt, expr, flags);
+ get_mem_ref_operands (fn, stmt, expr, flags);
return;
case TARGET_MEM_REF:
- get_tmr_operands (stmt, expr, flags);
+ get_tmr_operands (fn, stmt, expr, flags);
return;
case ARRAY_REF:
&& TREE_THIS_VOLATILE (expr))
gimple_set_has_volatile_ops (stmt, true);
- get_expr_operands (stmt, &TREE_OPERAND (expr, 0), flags);
+ get_expr_operands (fn, stmt, &TREE_OPERAND (expr, 0), flags);
if (code == COMPONENT_REF)
{
if (!(flags & opf_no_vops)
&& TREE_THIS_VOLATILE (TREE_OPERAND (expr, 1)))
gimple_set_has_volatile_ops (stmt, true);
- get_expr_operands (stmt, &TREE_OPERAND (expr, 2), uflags);
+ get_expr_operands (fn, stmt, &TREE_OPERAND (expr, 2), uflags);
}
else if (code == ARRAY_REF || code == ARRAY_RANGE_REF)
{
- get_expr_operands (stmt, &TREE_OPERAND (expr, 1), uflags);
- get_expr_operands (stmt, &TREE_OPERAND (expr, 2), uflags);
- get_expr_operands (stmt, &TREE_OPERAND (expr, 3), uflags);
+ get_expr_operands (fn, stmt, &TREE_OPERAND (expr, 1), uflags);
+ get_expr_operands (fn, stmt, &TREE_OPERAND (expr, 2), uflags);
+ get_expr_operands (fn, stmt, &TREE_OPERAND (expr, 3), uflags);
}
return;
case WITH_SIZE_EXPR:
/* WITH_SIZE_EXPR is a pass-through reference to its first argument,
and an rvalue reference to its second argument. */
- get_expr_operands (stmt, &TREE_OPERAND (expr, 1), uflags);
- get_expr_operands (stmt, &TREE_OPERAND (expr, 0), flags);
+ get_expr_operands (fn, stmt, &TREE_OPERAND (expr, 1), uflags);
+ get_expr_operands (fn, stmt, &TREE_OPERAND (expr, 0), flags);
return;
case COND_EXPR:
case VEC_COND_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);
+ get_expr_operands (fn, stmt, &TREE_OPERAND (expr, 0), uflags);
+ get_expr_operands (fn, stmt, &TREE_OPERAND (expr, 1), uflags);
+ get_expr_operands (fn, stmt, &TREE_OPERAND (expr, 2), uflags);
return;
case CONSTRUCTOR:
for (idx = 0;
vec_safe_iterate (CONSTRUCTOR_ELTS (expr), idx, &ce);
idx++)
- get_expr_operands (stmt, &ce->value, uflags);
+ get_expr_operands (fn, stmt, &ce->value, uflags);
return;
}
case VIEW_CONVERT_EXPR:
do_unary:
- get_expr_operands (stmt, &TREE_OPERAND (expr, 0), flags);
+ get_expr_operands (fn, stmt, &TREE_OPERAND (expr, 0), flags);
return;
case COMPOUND_EXPR:
case ASSERT_EXPR:
do_binary:
{
- get_expr_operands (stmt, &TREE_OPERAND (expr, 0), flags);
- get_expr_operands (stmt, &TREE_OPERAND (expr, 1), flags);
+ get_expr_operands (fn, stmt, &TREE_OPERAND (expr, 0), flags);
+ get_expr_operands (fn, stmt, &TREE_OPERAND (expr, 1), flags);
return;
}
case WIDEN_MULT_MINUS_EXPR:
case FMA_EXPR:
{
- get_expr_operands (stmt, &TREE_OPERAND (expr, 0), flags);
- get_expr_operands (stmt, &TREE_OPERAND (expr, 1), flags);
- get_expr_operands (stmt, &TREE_OPERAND (expr, 2), flags);
+ get_expr_operands (fn, stmt, &TREE_OPERAND (expr, 0), flags);
+ get_expr_operands (fn, stmt, &TREE_OPERAND (expr, 1), flags);
+ get_expr_operands (fn, stmt, &TREE_OPERAND (expr, 2), flags);
return;
}
build_* operand vectors will have potential operands in them. */
static void
-parse_ssa_operands (gimple stmt)
+parse_ssa_operands (struct function *fn, gimple stmt)
{
enum gimple_code code = gimple_code (stmt);
size_t i, n, start = 0;
switch (code)
{
case GIMPLE_ASM:
- get_asm_expr_operands (stmt);
+ get_asm_stmt_operands (fn, stmt);
break;
case GIMPLE_TRANSACTION:
/* The start of a transaction is a memory barrier. */
- add_virtual_operand (stmt, opf_def | opf_use);
+ add_virtual_operand (fn, stmt, opf_def | opf_use);
break;
case GIMPLE_DEBUG:
if (gimple_debug_bind_p (stmt)
&& gimple_debug_bind_has_value_p (stmt))
- get_expr_operands (stmt, gimple_debug_bind_get_value_ptr (stmt),
+ get_expr_operands (fn, stmt, gimple_debug_bind_get_value_ptr (stmt),
opf_use | opf_no_vops);
break;
case GIMPLE_RETURN:
- append_vuse (gimple_vop (cfun));
+ append_vuse (gimple_vop (fn));
goto do_default;
case GIMPLE_CALL:
/* Add call-clobbered operands, if needed. */
- maybe_add_call_vops (stmt);
+ maybe_add_call_vops (fn, stmt);
/* FALLTHRU */
case GIMPLE_ASSIGN:
- get_expr_operands (stmt, gimple_op_ptr (stmt, 0), opf_def);
+ get_expr_operands (fn, stmt, gimple_op_ptr (stmt, 0), opf_def);
start = 1;
/* FALLTHRU */
do_default:
n = gimple_num_ops (stmt);
for (i = start; i < n; i++)
- get_expr_operands (stmt, gimple_op_ptr (stmt, i), opf_use);
+ get_expr_operands (fn, stmt, gimple_op_ptr (stmt, i), opf_use);
break;
}
}
/* Create an operands cache for STMT. */
static void
-build_ssa_operands (gimple stmt)
+build_ssa_operands (struct function *fn, gimple stmt)
{
/* Initially assume that the statement has no volatile operands. */
gimple_set_has_volatile_ops (stmt, false);
start_ssa_stmt_operands ();
- parse_ssa_operands (stmt);
- finalize_ssa_stmt_operands (stmt);
+ parse_ssa_operands (fn, stmt);
+ finalize_ssa_stmt_operands (fn, stmt);
}
/* Verifies SSA statement operands. */
DEBUG_FUNCTION bool
-verify_ssa_operands (gimple stmt)
+verify_ssa_operands (struct function *fn, gimple stmt)
{
use_operand_p use_p;
def_operand_p def_p;
/* build_ssa_operands w/o finalizing them. */
gimple_set_has_volatile_ops (stmt, false);
start_ssa_stmt_operands ();
- parse_ssa_operands (stmt);
+ parse_ssa_operands (fn, stmt);
/* Now verify the built operands are the same as present in STMT. */
def = gimple_vdef (stmt);
the stmt operand lists. */
void
-free_stmt_operands (gimple stmt)
+free_stmt_operands (struct function *fn, gimple stmt)
{
use_optype_p uses = gimple_use_ops (stmt), last_use;
for (last_use = uses; last_use->next; last_use = last_use->next)
delink_imm_use (USE_OP_PTR (last_use));
delink_imm_use (USE_OP_PTR (last_use));
- last_use->next = gimple_ssa_operands (cfun)->free_uses;
- gimple_ssa_operands (cfun)->free_uses = uses;
+ last_use->next = gimple_ssa_operands (fn)->free_uses;
+ gimple_ssa_operands (fn)->free_uses = uses;
gimple_set_use_ops (stmt, NULL);
}
/* Get the operands of statement STMT. */
void
-update_stmt_operands (gimple stmt)
+update_stmt_operands (struct function *fn, gimple stmt)
{
/* If update_stmt_operands is called before SSA is initialized, do
nothing. */
- if (!ssa_operands_active (cfun))
+ if (!ssa_operands_active (fn))
return;
timevar_push (TV_TREE_OPS);
split_bbs_on_noreturn_calls during cfg cleanup. */
if (is_gimple_call (stmt)
&& gimple_call_noreturn_p (stmt))
- vec_safe_push (MODIFIED_NORETURN_CALLS (cfun), stmt);
+ vec_safe_push (MODIFIED_NORETURN_CALLS (fn), stmt);
gcc_assert (gimple_modified_p (stmt));
- build_ssa_operands (stmt);
+ build_ssa_operands (fn, stmt);
gimple_set_modified (stmt, false);
timevar_pop (TV_TREE_OPS);
op0 = *exp0;
op1 = *exp1;
- gcc_checking_assert (ssa_operands_active (cfun));
-
if (op0 != op1)
{
/* Attempt to preserve the relative positions of these two operands in
extern bool ssa_operands_active (struct function *);
extern void init_ssa_operands (struct function *fn);
-extern void fini_ssa_operands (void);
-extern bool verify_ssa_operands (gimple stmt);
-extern void free_stmt_operands (gimple);
-extern void update_stmt_operands (gimple);
+extern void fini_ssa_operands (struct function *);
+extern bool verify_ssa_operands (struct function *, gimple stmt);
+extern void free_stmt_operands (struct function *, gimple);
+extern void update_stmt_operands (struct function *, gimple);
extern void swap_ssa_operands (gimple, tree *, tree *);
extern bool verify_imm_links (FILE *f, tree var);
#include "coretypes.h"
#include "hash-table.h"
#include "tm.h"
-#include "ggc.h"
#include "tree.h"
#include "stor-layout.h"
#include "flags.h"
#include "tm_p.h"
#include "basic-block.h"
+#include "pointer-set.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimplify.h"
#include "gimple-iterator.h"
#include "tree-dfa.h"
#include "tree-pass.h"
#include "langhooks.h"
-#include "pointer-set.h"
#include "domwalk.h"
#include "cfgloop.h"
#include "tree-data-ref.h"
#include "tm_p.h"
#include "basic-block.h"
#include "gimple-pretty-print.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimplify.h"
#include "gimple-iterator.h"
#include "basic-block.h"
#include "gimple-pretty-print.h"
#include "tree-inline.h"
+#include "hash-table.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-fold.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimplify.h"
#include "gimple-iterator.h"
#include "expr.h"
#include "tree-dfa.h"
#include "tree-ssa.h"
-#include "hash-table.h"
#include "tree-iterator.h"
#include "alloc-pool.h"
#include "obstack.h"
#include "gimple-pretty-print.h"
#include "dumpfile.h"
#include "sbitmap.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-fold.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimplify.h"
#include "gimple-iterator.h"
#include "tree-ssa.h"
#include "tree-ssa-propagate.h"
#include "langhooks.h"
-#include "vec.h"
#include "value-prof.h"
/* This file implements a generic value propagation engine based on
for (i = 0; i < nargs; i++)
{
tree arg = CALL_EXPR_ARG (expr, i);
- if (is_gimple_reg_type (arg))
+ if (is_gimple_reg_type (TREE_TYPE (arg)))
{
if (!is_gimple_val (arg))
return false;
#include "basic-block.h"
#include "gimple-pretty-print.h"
#include "tree-inline.h"
+#include "pointer-set.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-fold.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimplify-me.h"
#include "tree-iterator.h"
#include "tree-pass.h"
#include "alloc-pool.h"
-#include "vec.h"
#include "langhooks.h"
-#include "pointer-set.h"
#include "cfgloop.h"
#include "flags.h"
#include "target.h"
tree new_lhs = make_ssa_name (TREE_TYPE (lhs), NULL);
enum tree_code rhs_code
= gimple_assign_rhs_code (cast_stmt);
- gimple g
- = gimple_build_assign_with_ops (rhs_code, new_lhs,
- new_op, NULL_TREE);
+ gimple g;
+ if (is_gimple_min_invariant (new_op))
+ {
+ new_op = fold_convert (TREE_TYPE (lhs), new_op);
+ g = gimple_build_assign (new_lhs, new_op);
+ }
+ else
+ g = gimple_build_assign_with_ops (rhs_code, new_lhs,
+ new_op, NULL_TREE);
gimple_stmt_iterator gsi = gsi_for_stmt (cast_stmt);
gimple_set_uid (g, gimple_uid (cast_stmt));
gimple_set_visited (g, true);
#include "basic-block.h"
#include "gimple-pretty-print.h"
#include "tree-inline.h"
+#include "hash-table.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-fold.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimplify.h"
#include "gimple-ssa.h"
#include "tree-dfa.h"
#include "tree-ssa.h"
#include "dumpfile.h"
-#include "hash-table.h"
#include "alloc-pool.h"
#include "flags.h"
#include "cfgloop.h"
#include "basic-block.h"
#include "gimple-pretty-print.h"
#include "tree-inline.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "stor-layout.h"
#include "hash-table.h"
#include "bitmap.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-fold.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimplify.h"
#include "gimple-iterator.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
-#include "ggc.h"
#include "obstack.h"
#include "bitmap.h"
#include "sbitmap.h"
#include "tree.h"
#include "stor-layout.h"
#include "stmt.h"
+#include "pointer-set.h"
+#include "hash-table.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "tree-dfa.h"
#include "tree-inline.h"
#include "diagnostic-core.h"
-#include "hash-table.h"
#include "function.h"
#include "tree-pass.h"
#include "alloc-pool.h"
#include "splay-tree.h"
#include "params.h"
#include "alias.h"
-#include "pointer-set.h"
/* The idea behind this analyzer is to generate set constraints from the
program, then solve the resulting constraints in order to generate the
return;
}
- /* Handle type-punning through unions. If we are extracting a pointer
- from a union via a possibly type-punning access that pointer
- points to anything, similar to a conversion of an integer to
- a pointer. */
- if (!lhs_p)
- {
- tree u;
- for (u = t;
- TREE_CODE (u) == COMPONENT_REF || TREE_CODE (u) == ARRAY_REF;
- u = TREE_OPERAND (u, 0))
- if (TREE_CODE (u) == COMPONENT_REF
- && TREE_CODE (TREE_TYPE (TREE_OPERAND (u, 0))) == UNION_TYPE)
- {
- struct constraint_expr temp;
-
- temp.offset = 0;
- temp.var = anything_id;
- temp.type = ADDRESSOF;
- results->safe_push (temp);
- return;
- }
- }
-
t = get_ref_base_and_extent (t, &bitpos, &bitsize, &bitmaxsize);
/* Pretend to take the address of the base, we'll take care of
#include "basic-block.h"
#include "flags.h"
#include "function.h"
+#include "hash-table.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "tree-phinodes.h"
#include "ssa-iterators.h"
#include "tree-into-ssa.h"
-#include "tree-ssa-alias.h"
#include "params.h"
-#include "hash-table.h"
#include "gimple-pretty-print.h"
#include "tree-ssa-sccvn.h"
#include "tree-dump.h"
#include "tree.h"
#include "gimple-pretty-print.h"
#include "bitmap.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "function.h"
#include "timevar.h"
#include "dumpfile.h"
+#include "pointer-set.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimple-ssa.h"
{
tree prev_x = SSA_NAME_VALUE (x);
- if (TREE_CODE (y) == SSA_NAME)
+ /* Y may be NULL if we are invalidating entries in the table. */
+ if (y && TREE_CODE (y) == SSA_NAME)
{
tree tmp = SSA_NAME_VALUE (y);
y = tmp ? tmp : y;
edge E. Record unwind information for the equivalences onto STACK.
If a PHI which prevents threading is encountered, then return FALSE
- indicating we should not thread this edge, else return TRUE. */
+ indicating we should not thread this edge, else return TRUE.
+
+ If SRC_MAP/DST_MAP exist, then mark the source and destination SSA_NAMEs
+ of any equivalences recorded. We use this to make invalidation after
+ traversing back edges less painful. */
static bool
-record_temporary_equivalences_from_phis (edge e, vec<tree> *stack)
+record_temporary_equivalences_from_phis (edge e, vec<tree> *stack,
+ bool backedge_seen,
+ bitmap src_map, bitmap dst_map)
{
gimple_stmt_iterator gsi;
stmt_count++;
record_temporary_equivalence (dst, src, stack);
+
+ /* If we have crossed a backedge, then start recording equivalences
+ we might need to invalidate. */
+ if (backedge_seen && TREE_CODE (src) == SSA_NAME)
+ {
+ bitmap_set_bit (src_map, SSA_NAME_VERSION (src));
+ bitmap_set_bit (dst_map, SSA_NAME_VERSION (dst));
+ }
}
return true;
}
}
}
+/* A new value has been assigned to LHS. If necessary, invalidate any
+ equivalences that are no longer valid. */
+static void
+invalidate_equivalences (tree lhs, vec<tree> *stack,
+ bitmap src_map, bitmap dst_map)
+{
+ /* SRC_MAP contains the source SSA_NAMEs for equivalences created by PHI
+ nodes. If an entry in SRC_MAP changes, there's some destination that
+ has been recorded as equivalent to the source and that equivalency
+ needs to be eliminated. */
+ if (bitmap_bit_p (src_map, SSA_NAME_VERSION (lhs)))
+ {
+ unsigned int i;
+ bitmap_iterator bi;
+
+ /* We know that the LHS of STMT was used as the RHS in an equivalency
+ created by a PHI. All the LHS of such PHIs were recorded into DST_MAP.
+ So we can iterate over them to see if any have the LHS of STMT as
+ an equivalence, and if so, remove the equivalence as it is no longer
+ valid. */
+ EXECUTE_IF_SET_IN_BITMAP (dst_map, 0, i, bi)
+ {
+ if (SSA_NAME_VALUE (ssa_name (i)) == lhs)
+ record_temporary_equivalence (ssa_name (i), NULL_TREE, stack);
+ }
+ }
+}
+
/* Try to simplify each statement in E->dest, ultimately leading to
a simplification of the COND_EXPR at the end of E->dest.
record_temporary_equivalences_from_stmts_at_dest (edge e,
vec<tree> *stack,
tree (*simplify) (gimple,
- gimple))
+ gimple),
+ bool backedge_seen,
+ bitmap src_map,
+ bitmap dst_map)
{
gimple stmt = NULL;
gimple_stmt_iterator gsi;
if (fndecl
&& (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_OBJECT_SIZE
|| DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CONSTANT_P))
- continue;
+ {
+ if (backedge_seen)
+ {
+ tree lhs = gimple_get_lhs (stmt);
+ record_temporary_equivalence (lhs, NULL_TREE, stack);
+ invalidate_equivalences (lhs, stack, src_map, dst_map);
+ }
+ continue;
+ }
}
/* At this point we have a statement which assigns an RHS to an
}
/* Record the context sensitive equivalence if we were able
- to simplify this statement. */
+ to simplify this statement.
+
+ If we have traversed a backedge at some point during threading,
+ then always enter something here. Either a real equivalence,
+ or a NULL_TREE equivalence which is effectively invalidation of
+ prior equivalences. */
if (cached_lhs
&& (TREE_CODE (cached_lhs) == SSA_NAME
|| is_gimple_min_invariant (cached_lhs)))
record_temporary_equivalence (gimple_get_lhs (stmt), cached_lhs, stack);
+ else if (backedge_seen)
+ record_temporary_equivalence (gimple_get_lhs (stmt), NULL_TREE, stack);
+
+ if (backedge_seen)
+ invalidate_equivalences (gimple_get_lhs (stmt), stack,
+ src_map, dst_map);
}
return stmt;
}
+/* Once we have passed a backedge in the CFG when threading, we do not want to
+ utilize edge equivalences for simplification purpose. They are no longer
+ necessarily valid. We use this callback rather than the ones provided by
+ DOM/VRP to achieve that effect. */
+static tree
+dummy_simplify (gimple stmt1 ATTRIBUTE_UNUSED, gimple stmt2 ATTRIBUTE_UNUSED)
+{
+ return NULL_TREE;
+}
+
/* Simplify the control statement at the end of the block E->dest.
To avoid allocating memory unnecessarily, a scratch GIMPLE_COND
return cached_lhs;
}
-/* Return TRUE if the statement at the end of e->dest depends on
- the output of any statement in BB. Otherwise return FALSE.
-
- This is used when we are threading a backedge and need to ensure
- that temporary equivalences from BB do not affect the condition
- in e->dest. */
-
-static bool
-cond_arg_set_in_bb (edge e, basic_block bb)
-{
- ssa_op_iter iter;
- use_operand_p use_p;
- gimple last = last_stmt (e->dest);
-
- /* E->dest does not have to end with a control transferring
- instruction. This can occur when we try to extend a jump
- threading opportunity deeper into the CFG. In that case
- it is safe for this check to return false. */
- if (!last)
- return false;
-
- if (gimple_code (last) != GIMPLE_COND
- && gimple_code (last) != GIMPLE_GOTO
- && gimple_code (last) != GIMPLE_SWITCH)
- return false;
-
- FOR_EACH_SSA_USE_OPERAND (use_p, last, iter, SSA_OP_USE | SSA_OP_VUSE)
- {
- tree use = USE_FROM_PTR (use_p);
-
- if (TREE_CODE (use) == SSA_NAME
- && gimple_code (SSA_NAME_DEF_STMT (use)) != GIMPLE_PHI
- && gimple_bb (SSA_NAME_DEF_STMT (use)) == bb)
- return true;
- }
- return false;
-}
-
/* Copy debug stmts from DEST's chain of single predecessors up to
SRC, so that we don't lose the bindings as PHI nodes are introduced
when DEST gains new predecessors. */
path->safe_push (x);
bitmap_set_bit (visited, taken_edge->dest->index);
*backedge_seen_p |= ((taken_edge->flags & EDGE_DFS_BACK) != 0);
+ if (*backedge_seen_p)
+ simplify = dummy_simplify;
return thread_around_empty_blocks (taken_edge,
dummy_cond,
handle_dominating_asserts,
&& gimple_code (stmt) != GIMPLE_SWITCH)
return false;
+ /* If we have traversed a backedge, then we do not want to look
+ at certain expressions in the table that can not be relied upon.
+ Luckily the only code that looked at those expressions is the
+ SIMPLIFY callback, which we replace if we can no longer use it. */
+ if (*backedge_seen_p)
+ simplify = dummy_simplify;
+
/* Extract and simplify the condition. */
cond = simplify_control_stmt_condition (taken_edge, stmt, dummy_cond,
simplify, handle_dominating_asserts);
= new jump_thread_edge (taken_edge, EDGE_NO_COPY_SRC_BLOCK);
path->safe_push (x);
*backedge_seen_p |= ((taken_edge->flags & EDGE_DFS_BACK) != 0);
+ if (*backedge_seen_p)
+ simplify = dummy_simplify;
thread_around_empty_blocks (taken_edge,
dummy_cond,
tree (*simplify) (gimple, gimple),
vec<jump_thread_edge *> *path,
bitmap visited,
- bool *backedge_seen_p)
+ bool *backedge_seen_p,
+ bitmap src_map,
+ bitmap dst_map)
{
- /* If we have crossed a backedge, then we want to verify that the COND_EXPR,
- SWITCH_EXPR or GOTO_EXPR at the end of e->dest is not affected
- by any statements in e->dest. If it is affected, then it is not
- safe to thread this edge. */
- if (*backedge_seen_p
- && cond_arg_set_in_bb (e, e->dest))
- return false;
+ /* If we have traversed a backedge, then we do not want to look
+ at certain expressions in the table that can not be relied upon.
+ Luckily the only code that looked at those expressions is the
+ SIMPLIFY callback, which we replace if we can no longer use it. */
+ if (*backedge_seen_p)
+ simplify = dummy_simplify;
/* PHIs create temporary equivalences. */
- if (!record_temporary_equivalences_from_phis (e, stack))
+ if (!record_temporary_equivalences_from_phis (e, stack, *backedge_seen_p,
+ src_map, dst_map))
return false;
/* Now walk each statement recording any context sensitive
temporary equivalences we can detect. */
gimple stmt
- = record_temporary_equivalences_from_stmts_at_dest (e, stack, simplify);
+ = record_temporary_equivalences_from_stmts_at_dest (e, stack, simplify,
+ *backedge_seen_p,
+ src_map, dst_map);
if (!stmt)
return false;
= new jump_thread_edge (taken_edge, EDGE_COPY_SRC_BLOCK);
path->safe_push (x);
*backedge_seen_p |= ((taken_edge->flags & EDGE_DFS_BACK) != 0);
+ if (*backedge_seen_p)
+ simplify = dummy_simplify;
/* See if we can thread through DEST as well, this helps capture
secondary effects of threading without having to re-run DOM or
- VRP. */
- if (!*backedge_seen_p
- || ! cond_arg_set_in_bb (taken_edge, e->dest))
- {
- /* We don't want to thread back to a block we have already
- visited. This may be overly conservative. */
- bitmap_set_bit (visited, dest->index);
- bitmap_set_bit (visited, e->dest->index);
- thread_around_empty_blocks (taken_edge,
- dummy_cond,
- handle_dominating_asserts,
- simplify,
- visited,
- path,
- backedge_seen_p);
- }
+ VRP.
+
+ We don't want to thread back to a block we have already
+ visited. This may be overly conservative. */
+ bitmap_set_bit (visited, dest->index);
+ bitmap_set_bit (visited, e->dest->index);
+ thread_around_empty_blocks (taken_edge,
+ dummy_cond,
+ handle_dominating_asserts,
+ simplify,
+ visited,
+ path,
+ backedge_seen_p);
return true;
}
}
tree (*simplify) (gimple, gimple))
{
bitmap visited = BITMAP_ALLOC (NULL);
+ bitmap src_map = BITMAP_ALLOC (NULL);
+ bitmap dst_map = BITMAP_ALLOC (NULL);
bool backedge_seen;
stmt_count = 0;
bitmap_set_bit (visited, e->src->index);
bitmap_set_bit (visited, e->dest->index);
backedge_seen = ((e->flags & EDGE_DFS_BACK) != 0);
+ if (backedge_seen)
+ simplify = dummy_simplify;
+
if (thread_through_normal_block (e, dummy_cond, handle_dominating_asserts,
stack, simplify, path, visited,
- &backedge_seen))
+ &backedge_seen, src_map, dst_map))
{
propagate_threaded_block_debug_into (path->last ()->e->dest,
e->dest);
remove_temporary_equivalences (stack);
BITMAP_FREE (visited);
+ BITMAP_FREE (src_map);
+ BITMAP_FREE (dst_map);
register_jump_thread (path);
return;
}
{
remove_temporary_equivalences (stack);
BITMAP_FREE (visited);
+ BITMAP_FREE (src_map);
+ BITMAP_FREE (dst_map);
return;
}
+ /* We need to restore the state of the maps to this point each loop
+ iteration. */
+ bitmap src_map_copy = BITMAP_ALLOC (NULL);
+ bitmap dst_map_copy = BITMAP_ALLOC (NULL);
+ bitmap_copy (src_map_copy, src_map);
+ bitmap_copy (dst_map_copy, dst_map);
+
/* Look at each successor of E->dest to see if we can thread through it. */
FOR_EACH_EDGE (taken_edge, ei, e->dest->succs)
{
/* Push a fresh marker so we can unwind the equivalences created
for each of E->dest's successors. */
stack->safe_push (NULL_TREE);
+ bitmap_copy (src_map, src_map_copy);
+ bitmap_copy (dst_map, dst_map_copy);
/* Avoid threading to any block we have already visited. */
bitmap_clear (visited);
found = false;
backedge_seen = ((e->flags & EDGE_DFS_BACK) != 0);
backedge_seen |= ((taken_edge->flags & EDGE_DFS_BACK) != 0);
- if (!backedge_seen
- || ! cond_arg_set_in_bb (path->last ()->e, e->dest))
- found = thread_around_empty_blocks (taken_edge,
- dummy_cond,
- handle_dominating_asserts,
- simplify,
- visited,
- path,
- &backedge_seen);
-
- if (!found
- && (!backedge_seen
- || ! cond_arg_set_in_bb (path->last ()->e, e->dest)))
+ if (backedge_seen)
+ simplify = dummy_simplify;
+ found = thread_around_empty_blocks (taken_edge,
+ dummy_cond,
+ handle_dominating_asserts,
+ simplify,
+ visited,
+ path,
+ &backedge_seen);
+
+ if (backedge_seen)
+ simplify = dummy_simplify;
+
+ if (!found)
found = thread_through_normal_block (path->last ()->e, dummy_cond,
handle_dominating_asserts,
stack, simplify, path, visited,
- &backedge_seen);
+ &backedge_seen,
+ src_map, dst_map);
/* If we were able to thread through a successor of E->dest, then
record the jump threading opportunity. */
remove_temporary_equivalences (stack);
}
BITMAP_FREE (visited);
+ BITMAP_FREE (src_map);
+ BITMAP_FREE (dst_map);
+ BITMAP_FREE (src_map_copy);
+ BITMAP_FREE (dst_map_copy);
}
remove_temporary_equivalences (stack);
#include "flags.h"
#include "basic-block.h"
#include "function.h"
+#include "hash-table.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "ssa-iterators.h"
#include "dumpfile.h"
#include "cfgloop.h"
-#include "hash-table.h"
#include "dbgcnt.h"
#include "tree-cfg.h"
#include "tree-pass.h"
e->probability = REG_BR_PROB_BASE;
e->count = bb->count;
- /* We have to copy path -- which means creating a new vector as well
- as all the jump_thread_edge entries. */
- if (rd->path->last ()->e->aux)
- {
- vec<jump_thread_edge *> *path = THREAD_PATH (rd->path->last ()->e);
- vec<jump_thread_edge *> *copy = new vec<jump_thread_edge *> ();
+ /* We used to copy the thread path here. That was added in 2007
+ and dutifully updated through the representation changes in 2013.
- /* Sadly, the elements of the vector are pointers and need to
- be copied as well. */
- for (unsigned int i = 0; i < path->length (); i++)
- {
- jump_thread_edge *x
- = new jump_thread_edge ((*path)[i]->e, (*path)[i]->type);
- copy->safe_push (x);
- }
- e->aux = (void *)copy;
- }
- else
- {
- e->aux = NULL;
- }
+ In 2013 we added code to thread from an interior node through
+ the backedge to another interior node. That runs after the code
+ to thread through loop headers from outside the loop.
+
+ The latter may delete edges in the CFG, including those
+ which appeared in the jump threading path we copied here. Thus
+ we'd end up using a dangling pointer.
+
+ After reviewing the 2007/2011 code, I can't see how anything
+ depended on copying the AUX field and clearly copying the jump
+ threading path is problematical due to embedded edge pointers.
+ It has been removed. */
+ e->aux = NULL;
/* If there are any PHI nodes at the destination of the outgoing edge
from the duplicate block, then we will need to add a new argument
bitmap_iterator bi;
bitmap threaded_blocks;
struct loop *loop;
- bool totally_clobbered_loops = false;
/* We must know about loops in order to preserve them. */
gcc_assert (current_loops != NULL);
/* Our path is still valid, thread it. */
if (e->aux)
{
- totally_clobbered_loops
- |= thread_block ((*path)[0]->e->dest, false);
- e->aux = NULL;
+ struct loop *loop = (*path)[0]->e->dest->loop_father;
+
+ if (thread_block ((*path)[0]->e->dest, false))
+ {
+ /* This jump thread likely totally scrambled this loop.
+ So arrange for it to be fixed up. */
+ loop->header = NULL;
+ loop->latch = NULL;
+ e->aux = NULL;
+ }
+ else
+ {
+ delete_jump_thread_path (path);
+ e->aux = NULL;
+ ei_next (&ei);
+ }
}
}
else
threaded_blocks = NULL;
paths.release ();
- /* If we made changes to the CFG that might have totally messed
- up the loop structure, then drop the old loop structure and
- rebuild. */
- if (totally_clobbered_loops)
- {
- /* Release the current loop structures, they are totally
- clobbered at this point. */
- loop_optimizer_finalize ();
- current_loops = NULL;
-
- /* Similarly for dominance information. */
- free_dominance_info (CDI_DOMINATORS);
- free_dominance_info (CDI_POST_DOMINATORS);
-
- /* Before we can rebuild the loop structures, we need dominators,
- which requires no unreachable code. So remove unreachable code. */
- delete_unreachable_blocks ();
-
- /* Now rebuild the loop structures. */
- cfun->curr_properties &= ~PROP_loops;
- loop_optimizer_init (AVOID_CFG_MODIFICATIONS);
- cfun->curr_properties |= PROP_loops;
- retval = 1;
- }
-
- if (retval && current_loops)
+ if (retval)
loops_state_set (LOOPS_NEED_FIXUP);
return retval;
#include "tm_p.h"
#include "basic-block.h"
#include "function.h"
+#include "hash-table.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "gimple-pretty-print.h"
#include "bitmap.h"
#include "pointer-set.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "flags.h"
#include "tm_p.h"
#include "target.h"
-#include "ggc.h"
#include "langhooks.h"
#include "basic-block.h"
#include "function.h"
#include "gimple-pretty-print.h"
#include "pointer-set.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-fold.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimplify.h"
#include "gimple-iterator.h"
goto err;
}
- if (verify_ssa_operands (stmt))
+ if (verify_ssa_operands (cfun, stmt))
{
print_gimple_stmt (stderr, stmt, 0, TDF_VOPS);
goto err;
/* We no longer maintain the SSA operand cache at this point. */
if (ssa_operands_active (cfun))
- fini_ssa_operands ();
+ fini_ssa_operands (cfun);
htab_delete (cfun->gimple_df->default_defs);
cfun->gimple_df->default_defs = NULL;
#include "tm.h"
#include "tree.h"
#include "stor-layout.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-ssa.h"
#include "tree-phinodes.h"
other fields must be assumed clobbered. */
void
-release_ssa_name (tree var)
+release_ssa_name_fn (struct function *fn, tree var)
{
if (!var)
return;
while (imm->next != imm)
delink_imm_use (imm->next);
- (*SSANAMES (cfun))[SSA_NAME_VERSION (var)] = NULL_TREE;
+ (*SSANAMES (fn))[SSA_NAME_VERSION (var)] = NULL_TREE;
memset (var, 0, tree_size (var));
imm->prev = imm;
SSA_NAME_IN_FREE_LIST (var) = 1;
/* And finally put it on the free list. */
- vec_safe_push (FREE_SSANAMES (cfun), var);
+ vec_safe_push (FREE_SSANAMES (fn), var);
}
}
extern void fini_ssanames (void);
extern void ssanames_print_statistics (void);
extern tree make_ssa_name_fn (struct function *, tree, gimple);
-extern void release_ssa_name (tree);
+extern void release_ssa_name_fn (struct function *, tree);
extern bool get_ptr_info_alignment (struct ptr_info_def *, unsigned int *,
unsigned int *);
extern void mark_ptr_info_alignment_unknown (struct ptr_info_def *);
return duplicate_ssa_name_fn (cfun, var, stmt);
}
+/* Release the SSA name NAME used in function cfun. */
+
+static inline void
+release_ssa_name (tree name)
+{
+ release_ssa_name_fn (cfun, name);
+}
+
/* Return an anonymous SSA_NAME node for type TYPE defined in statement STMT
in function cfun. Arrange so that it uses NAME in dumps. */
#include "gimple-pretty-print.h"
#include "target.h"
#include "bitmap.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimple-walk.h"
#include "diagnostic.h"
#include "tree.h"
#include "stringpool.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "tree-streamer.h"
#include "data-streamer.h"
}
+/* Unpack all the non-pointer fields of the TS_OMP_CLAUSE
+ structure of expression EXPR from bitpack BP. */
+
+static void
+unpack_ts_omp_clause_value_fields (struct data_in *data_in,
+ struct bitpack_d *bp, tree expr)
+{
+ OMP_CLAUSE_LOCATION (expr) = stream_input_location (bp, data_in);
+ switch (OMP_CLAUSE_CODE (expr))
+ {
+ case OMP_CLAUSE_DEFAULT:
+ OMP_CLAUSE_DEFAULT_KIND (expr)
+ = bp_unpack_enum (bp, omp_clause_default_kind,
+ OMP_CLAUSE_DEFAULT_LAST);
+ break;
+ case OMP_CLAUSE_SCHEDULE:
+ OMP_CLAUSE_SCHEDULE_KIND (expr)
+ = bp_unpack_enum (bp, omp_clause_schedule_kind,
+ OMP_CLAUSE_SCHEDULE_LAST);
+ break;
+ case OMP_CLAUSE_DEPEND:
+ OMP_CLAUSE_DEPEND_KIND (expr)
+ = bp_unpack_enum (bp, omp_clause_depend_kind, OMP_CLAUSE_DEPEND_LAST);
+ break;
+ case OMP_CLAUSE_MAP:
+ OMP_CLAUSE_MAP_KIND (expr)
+ = bp_unpack_enum (bp, omp_clause_map_kind, OMP_CLAUSE_MAP_LAST);
+ break;
+ case OMP_CLAUSE_PROC_BIND:
+ OMP_CLAUSE_PROC_BIND_KIND (expr)
+ = bp_unpack_enum (bp, omp_clause_proc_bind_kind,
+ OMP_CLAUSE_PROC_BIND_LAST);
+ break;
+ case OMP_CLAUSE_REDUCTION:
+ OMP_CLAUSE_REDUCTION_CODE (expr)
+ = bp_unpack_enum (bp, tree_code, MAX_TREE_CODES);
+ break;
+ default:
+ break;
+ }
+}
+
/* Unpack all the non-pointer fields in EXPR into a bit pack. */
static void
if (length > 0)
vec_safe_grow (CONSTRUCTOR_ELTS (expr), length);
}
+
+ if (code == OMP_CLAUSE)
+ unpack_ts_omp_clause_value_fields (data_in, bp, expr);
}
unsigned HOST_WIDE_INT nargs = streamer_read_uhwi (ib);
return build_vl_exp (CALL_EXPR, nargs + 3);
}
+ else if (code == OMP_CLAUSE)
+ {
+ enum omp_clause_code subcode
+ = (enum omp_clause_code) streamer_read_uhwi (ib);
+ return build_omp_clause (UNKNOWN_LOCATION, subcode);
+ }
else
{
/* For all other nodes, materialize the tree with a raw
}
+/* Read all pointer fields in the TS_OMP_CLAUSE structure of EXPR from
+ input block IB. DATA_IN contains tables and descriptors for the
+ file being read. */
+
+static void
+lto_input_ts_omp_clause_tree_pointers (struct lto_input_block *ib,
+ struct data_in *data_in, tree expr)
+{
+ int i;
+
+ for (i = 0; i < omp_clause_num_ops[OMP_CLAUSE_CODE (expr)]; i++)
+ OMP_CLAUSE_OPERAND (expr, i) = stream_read_tree (ib, data_in);
+ OMP_CLAUSE_CHAIN (expr) = stream_read_tree (ib, data_in);
+}
+
+
/* Read all pointer fields in EXPR from input block IB. DATA_IN
contains tables and descriptors for the file being read. */
if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR))
lto_input_ts_constructor_tree_pointers (ib, data_in, expr);
+
+ if (code == OMP_CLAUSE)
+ lto_input_ts_omp_clause_tree_pointers (ib, data_in, expr);
}
#include "diagnostic.h"
#include "tree.h"
#include "stor-layout.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "tree-streamer.h"
#include "data-streamer.h"
}
+/* Pack all the non-pointer fields of the TS_OMP_CLAUSE structure
+ of expression EXPR into bitpack BP. */
+
+static void
+pack_ts_omp_clause_value_fields (struct output_block *ob,
+ struct bitpack_d *bp, tree expr)
+{
+ stream_output_location (ob, bp, OMP_CLAUSE_LOCATION (expr));
+ switch (OMP_CLAUSE_CODE (expr))
+ {
+ case OMP_CLAUSE_DEFAULT:
+ bp_pack_enum (bp, omp_clause_default_kind, OMP_CLAUSE_DEFAULT_LAST,
+ OMP_CLAUSE_DEFAULT_KIND (expr));
+ break;
+ case OMP_CLAUSE_SCHEDULE:
+ bp_pack_enum (bp, omp_clause_schedule_kind, OMP_CLAUSE_SCHEDULE_LAST,
+ OMP_CLAUSE_SCHEDULE_KIND (expr));
+ break;
+ case OMP_CLAUSE_DEPEND:
+ bp_pack_enum (bp, omp_clause_depend_kind, OMP_CLAUSE_DEPEND_LAST,
+ OMP_CLAUSE_DEPEND_KIND (expr));
+ break;
+ case OMP_CLAUSE_MAP:
+ bp_pack_enum (bp, omp_clause_map_kind, OMP_CLAUSE_MAP_LAST,
+ OMP_CLAUSE_MAP_KIND (expr));
+ break;
+ case OMP_CLAUSE_PROC_BIND:
+ bp_pack_enum (bp, omp_clause_proc_bind_kind, OMP_CLAUSE_PROC_BIND_LAST,
+ OMP_CLAUSE_PROC_BIND_KIND (expr));
+ break;
+ case OMP_CLAUSE_REDUCTION:
+ bp_pack_enum (bp, tree_code, MAX_TREE_CODES,
+ OMP_CLAUSE_REDUCTION_CODE (expr));
+ break;
+ default:
+ break;
+ }
+}
+
+
/* Pack all the bitfields in EXPR into a bit pack. */
void
if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR))
bp_pack_var_len_unsigned (bp, CONSTRUCTOR_NELTS (expr));
+
+ if (code == OMP_CLAUSE)
+ pack_ts_omp_clause_value_fields (ob, bp, expr);
}
}
}
+
+/* Write all pointer fields in the TS_OMP_CLAUSE structure of EXPR
+ to output block OB. If REF_P is true, write a reference to EXPR's
+ pointer fields. */
+
+static void
+write_ts_omp_clause_tree_pointers (struct output_block *ob, tree expr,
+ bool ref_p)
+{
+ int i;
+ for (i = 0; i < omp_clause_num_ops[OMP_CLAUSE_CODE (expr)]; i++)
+ stream_write_tree (ob, OMP_CLAUSE_OPERAND (expr, i), ref_p);
+ if (OMP_CLAUSE_CODE (expr) == OMP_CLAUSE_REDUCTION)
+ {
+ /* We don't stream these right now, handle it if streaming
+ of them is needed. */
+ gcc_assert (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (expr) == NULL);
+ gcc_assert (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (expr) == NULL);
+ }
+ stream_write_tree (ob, OMP_CLAUSE_CHAIN (expr), ref_p);
+}
+
+
/* Write all pointer fields in EXPR to output block OB. If REF_P is true,
the leaves of EXPR are emitted as references. */
if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR))
write_ts_constructor_tree_pointers (ob, expr, ref_p);
+
+ if (code == OMP_CLAUSE)
+ write_ts_omp_clause_tree_pointers (ob, expr, ref_p);
}
streamer_write_uhwi (ob, BINFO_N_BASE_BINFOS (expr));
else if (TREE_CODE (expr) == CALL_EXPR)
streamer_write_uhwi (ob, call_expr_nargs (expr));
+ else if (TREE_CODE (expr) == OMP_CLAUSE)
+ streamer_write_uhwi (ob, OMP_CLAUSE_CODE (expr));
else if (CODE_CONTAINS_STRUCT (code, TS_INT_CST))
{
gcc_checking_assert (TREE_INT_CST_NUNITS (expr));
#include "system.h"
#include "coretypes.h"
#include "tree.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "streamer-hooks.h"
#include "tree-streamer.h"
#include "varasm.h"
#include "stor-layout.h"
#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimplify.h"
#include "gimple-iterator.h"
#include "tm_p.h"
#include "basic-block.h"
#include "function.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimplify-me.h"
#include "coretypes.h"
#include "dumpfile.h"
#include "tm.h"
-#include "ggc.h"
#include "tree.h"
#include "stor-layout.h"
#include "tm_p.h"
#include "target.h"
#include "basic-block.h"
#include "gimple-pretty-print.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimplify.h"
#include "gimple-iterator.h"
#include "tree-scalar-evolution.h"
#include "tree-vectorizer.h"
#include "diagnostic-core.h"
+#include "cgraph.h"
/* Need to include rtl.h, expr.h, etc. for optabs. */
#include "expr.h"
#include "optabs.h"
*new_slot = slot;
}
- if (!supportable_dr_alignment && unlimited_cost_model ())
+ if (!supportable_dr_alignment
+ && unlimited_cost_model (LOOP_VINFO_LOOP (loop_vinfo)))
slot->count += VECT_MAX_COST;
}
res.peel_info.dr = NULL;
res.body_cost_vec = stmt_vector_for_cost ();
- if (!unlimited_cost_model ())
+ if (!unlimited_cost_model (LOOP_VINFO_LOOP (loop_vinfo)))
{
res.inside_cost = INT_MAX;
res.outside_cost = INT_MAX;
vectorization factor.
We do this automtically for cost model, since we calculate cost
for every peeling option. */
- if (unlimited_cost_model ())
+ if (unlimited_cost_model (LOOP_VINFO_LOOP (loop_vinfo)))
possible_npeel_number = vf /nelements;
/* Handle the aligned case. We may decide to align some other
if (DR_MISALIGNMENT (dr) == 0)
{
npeel_tmp = 0;
- if (unlimited_cost_model ())
+ if (unlimited_cost_model (LOOP_VINFO_LOOP (loop_vinfo)))
possible_npeel_number++;
}
if (loop_vinfo)
{
+ basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
+
loop = LOOP_VINFO_LOOP (loop_vinfo);
- if (!find_loop_nest (loop, &LOOP_VINFO_LOOP_NEST (loop_vinfo))
- || find_data_references_in_loop
- (loop, &LOOP_VINFO_DATAREFS (loop_vinfo)))
+ datarefs = LOOP_VINFO_DATAREFS (loop_vinfo);
+ if (!find_loop_nest (loop, &LOOP_VINFO_LOOP_NEST (loop_vinfo)))
{
if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
return false;
}
- datarefs = LOOP_VINFO_DATAREFS (loop_vinfo);
+ for (i = 0; i < loop->num_nodes; i++)
+ {
+ gimple_stmt_iterator gsi;
+
+ for (gsi = gsi_start_bb (bbs[i]); !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ gimple stmt = gsi_stmt (gsi);
+ if (!find_data_references_in_stmt (loop, stmt, &datarefs))
+ {
+ if (is_gimple_call (stmt) && loop->safelen)
+ {
+ tree fndecl = gimple_call_fndecl (stmt), op;
+ if (fndecl != NULL_TREE)
+ {
+ struct cgraph_node *node = cgraph_get_node (fndecl);
+ if (node != NULL && node->simd_clones != NULL)
+ {
+ unsigned int j, n = gimple_call_num_args (stmt);
+ for (j = 0; j < n; j++)
+ {
+ op = gimple_call_arg (stmt, j);
+ if (DECL_P (op)
+ || (REFERENCE_CLASS_P (op)
+ && get_base_address (op)))
+ break;
+ }
+ op = gimple_call_lhs (stmt);
+ /* Ignore #pragma omp declare simd functions
+ if they don't have data references in the
+ call stmt itself. */
+ if (j == n
+ && !(op
+ && (DECL_P (op)
+ || (REFERENCE_CLASS_P (op)
+ && get_base_address (op)))))
+ continue;
+ }
+ }
+ }
+ LOOP_VINFO_DATAREFS (loop_vinfo) = datarefs;
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: loop contains function "
+ "calls or data references that cannot "
+ "be analyzed\n");
+ return false;
+ }
+ }
+ }
+
+ LOOP_VINFO_DATAREFS (loop_vinfo) = datarefs;
}
else
{
#include "stor-layout.h"
#include "tm.h"
#include "langhooks.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimplify-me.h"
#include "tree-iterator.h"
#include "tree-pass.h"
#include "flags.h"
-#include "ggc.h"
#include "diagnostic.h"
#include "target.h"
tree *cst;
gimple g;
tree base = NULL_TREE;
+ optab op;
if (nelts <= 2 || CONSTRUCTOR_NELTS (rhs) != nelts)
return;
+ op = optab_for_tree_code (PLUS_EXPR, type, optab_default);
+ if (op == unknown_optab
+ || optab_handler (op, TYPE_MODE (type)) == CODE_FOR_nothing)
+ return;
FOR_EACH_VEC_SAFE_ELT (CONSTRUCTOR_ELTS (rhs), i, elt)
if (TREE_CODE (elt->value) != SSA_NAME
|| TREE_CODE (TREE_TYPE (elt->value)) == VECTOR_TYPE)
#include "coretypes.h"
#include "dumpfile.h"
#include "tm.h"
-#include "ggc.h"
#include "tree.h"
#include "basic-block.h"
#include "gimple-pretty-print.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimplify.h"
#include "gimple-iterator.h"
#include "coretypes.h"
#include "dumpfile.h"
#include "tm.h"
-#include "ggc.h"
#include "tree.h"
#include "stor-layout.h"
#include "basic-block.h"
#include "gimple-pretty-print.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimplify.h"
#include "gimple-iterator.h"
if (gimple_get_lhs (stmt) == NULL_TREE)
{
+ if (is_gimple_call (stmt))
+ {
+ /* Ignore calls with no lhs. These must be calls to
+ #pragma omp simd functions, and what vectorization factor
+ it really needs can't be determined until
+ vectorizable_simd_clone_call. */
+ if (!analyze_pattern_stmt && gsi_end_p (pattern_def_si))
+ {
+ pattern_def_seq = NULL;
+ gsi_next (&si);
+ }
+ continue;
+ }
if (dump_enabled_p ())
{
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
void *target_cost_data = LOOP_VINFO_TARGET_COST_DATA (loop_vinfo);
/* Cost model disabled. */
- if (unlimited_cost_model ())
+ if (unlimited_cost_model (LOOP_VINFO_LOOP (loop_vinfo)))
{
dump_printf_loc (MSG_NOTE, vect_location, "cost model disabled.\n");
*ret_min_profitable_niters = 0;
/* vector version will never be profitable. */
else
{
+ if (LOOP_VINFO_LOOP (loop_vinfo)->force_vect)
+ warning_at (vect_location, OPT_Wopenmp_simd, "vectorization "
+ "did not happen for a simd loop");
+
if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
"cost model: the vector iteration cost = %d "
struct loop *iv_loop;
basic_block new_bb;
tree new_vec, vec_init, vec_step, t;
- tree access_fn;
tree new_var;
tree new_name;
gimple init_stmt, induction_phi, new_stmt;
tree init_expr, step_expr;
int vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
int i;
- bool ok;
int ncopies;
tree expr;
stmt_vec_info phi_info = vinfo_for_stmt (iv_phi);
latch_e = loop_latch_edge (iv_loop);
loop_arg = PHI_ARG_DEF_FROM_EDGE (iv_phi, latch_e);
- access_fn = analyze_scalar_evolution (iv_loop, PHI_RESULT (iv_phi));
- gcc_assert (access_fn);
- STRIP_NOPS (access_fn);
- ok = vect_is_simple_iv_evolution (iv_loop->num, access_fn,
- &init_expr, &step_expr);
- gcc_assert (ok);
+ step_expr = STMT_VINFO_LOOP_PHI_EVOLUTION_PART (phi_info);
+ gcc_assert (step_expr != NULL_TREE);
+
pe = loop_preheader_edge (iv_loop);
+ init_expr = PHI_ARG_DEF_FROM_EDGE (iv_phi,
+ loop_preheader_edge (iv_loop));
vectype = get_vectype_for_scalar_type (TREE_TYPE (init_expr));
resvectype = get_vectype_for_scalar_type (TREE_TYPE (PHI_RESULT (iv_phi)));
gcc_assert (phi_info);
gcc_assert (ncopies >= 1);
+ /* Convert the step to the desired type. */
+ step_expr = force_gimple_operand (fold_convert (TREE_TYPE (vectype),
+ step_expr),
+ &stmts, true, NULL_TREE);
+ if (stmts)
+ {
+ new_bb = gsi_insert_seq_on_edge_immediate (pe, stmts);
+ gcc_assert (!new_bb);
+ }
+
/* Find the first insertion point in the BB. */
si = gsi_after_labels (bb);
/* iv_loop is nested in the loop to be vectorized. init_expr had already
been created during vectorization of previous stmts. We obtain it
from the STMT_VINFO_VEC_STMT of the defining stmt. */
- tree iv_def = PHI_ARG_DEF_FROM_EDGE (iv_phi,
- loop_preheader_edge (iv_loop));
- vec_init = vect_get_vec_def_for_operand (iv_def, iv_phi, NULL);
+ vec_init = vect_get_vec_def_for_operand (init_expr, iv_phi, NULL);
/* If the initial value is not of proper type, convert it. */
if (!useless_type_conversion_p (vectype, TREE_TYPE (vec_init)))
{
int vectorization_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
bool grouped_store;
bool slp_scheduled = false;
- unsigned int nunits;
gimple stmt, pattern_stmt;
gimple_seq pattern_def_seq = NULL;
gimple_stmt_iterator pattern_def_si = gsi_none ();
transform_pattern_stmt = false;
}
- gcc_assert (STMT_VINFO_VECTYPE (stmt_info));
- nunits = (unsigned int) TYPE_VECTOR_SUBPARTS (
- STMT_VINFO_VECTYPE (stmt_info));
- if (!STMT_SLP_TYPE (stmt_info)
- && nunits != (unsigned int) vectorization_factor
- && dump_enabled_p ())
- /* For SLP VF is set according to unrolling factor, and not to
- vector size, hence for SLP this print is not valid. */
- dump_printf_loc (MSG_NOTE, vect_location,
- "multiple-types.\n");
+ if (STMT_VINFO_VECTYPE (stmt_info))
+ {
+ unsigned int nunits
+ = (unsigned int)
+ TYPE_VECTOR_SUBPARTS (STMT_VINFO_VECTYPE (stmt_info));
+ if (!STMT_SLP_TYPE (stmt_info)
+ && nunits != (unsigned int) vectorization_factor
+ && dump_enabled_p ())
+ /* For SLP VF is set according to unrolling factor, and not
+ to vector size, hence for SLP this print is not valid. */
+ dump_printf_loc (MSG_NOTE, vect_location, "multiple-types.\n");
+ }
/* SLP. Schedule all the SLP instances when the first SLP stmt is
reached. */
#include "system.h"
#include "coretypes.h"
#include "tm.h"
-#include "ggc.h"
#include "tree.h"
#include "stor-layout.h"
#include "target.h"
#include "basic-block.h"
#include "gimple-pretty-print.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimplify.h"
#include "gimple-iterator.h"
#include "coretypes.h"
#include "dumpfile.h"
#include "tm.h"
-#include "ggc.h"
#include "tree.h"
#include "stor-layout.h"
#include "target.h"
#include "basic-block.h"
#include "gimple-pretty-print.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimple-ssa.h"
}
/* Cost model: check if the vectorization is worthwhile. */
- if (!unlimited_cost_model ()
+ if (!unlimited_cost_model (NULL)
&& !vect_bb_vectorization_profitable_p (bb_vinfo))
{
if (dump_enabled_p ())
#include "coretypes.h"
#include "dumpfile.h"
#include "tm.h"
-#include "ggc.h"
#include "tree.h"
#include "stor-layout.h"
#include "target.h"
#include "basic-block.h"
#include "gimple-pretty-print.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimplify.h"
#include "gimple-iterator.h"
#include "tree-ssanames.h"
#include "tree-ssa-loop-manip.h"
#include "cfgloop.h"
+#include "tree-ssa-loop.h"
+#include "tree-scalar-evolution.h"
#include "expr.h"
#include "recog.h" /* FIXME: for insn_data */
#include "optabs.h"
#include "diagnostic-core.h"
#include "tree-vectorizer.h"
#include "dumpfile.h"
+#include "cgraph.h"
/* For lang_hooks.types.type_for_mode. */
#include "langhooks.h"
if (!is_gimple_call (stmt))
return false;
- if (TREE_CODE (gimple_call_lhs (stmt)) != SSA_NAME)
+ if (gimple_call_lhs (stmt) == NULL_TREE
+ || TREE_CODE (gimple_call_lhs (stmt)) != SSA_NAME)
return false;
- if (stmt_can_throw_internal (stmt))
- return false;
+ gcc_checking_assert (!stmt_can_throw_internal (stmt));
vectype_out = STMT_VINFO_VECTYPE (stmt_info);
vargs.release ();
- /* Update the exception handling table with the vector stmt if necessary. */
- if (maybe_clean_or_replace_eh_stmt (stmt, *vec_stmt))
- gimple_purge_dead_eh_edges (gimple_bb (stmt));
-
/* The call in STMT might prevent it from being removed in dce.
We however cannot remove it here, due to the way the ssa name
it defines is mapped to the new definition. So just replace
}
+struct simd_call_arg_info
+{
+ tree vectype;
+ tree op;
+ enum vect_def_type dt;
+ HOST_WIDE_INT linear_step;
+ unsigned int align;
+};
+
+/* Function vectorizable_simd_clone_call.
+
+ Check if STMT performs a function call that can be vectorized
+ by calling a simd clone of the function.
+ If VEC_STMT is also passed, vectorize the STMT: create a vectorized
+ stmt to replace it, put it in VEC_STMT, and insert it at BSI.
+ Return FALSE if not a vectorizable STMT, TRUE otherwise. */
+
+static bool
+vectorizable_simd_clone_call (gimple stmt, gimple_stmt_iterator *gsi,
+ gimple *vec_stmt, slp_tree slp_node)
+{
+ tree vec_dest;
+ tree scalar_dest;
+ tree op, type;
+ tree vec_oprnd0 = NULL_TREE;
+ stmt_vec_info stmt_info = vinfo_for_stmt (stmt), prev_stmt_info;
+ tree vectype;
+ unsigned int nunits;
+ loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
+ bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_info);
+ struct loop *loop = loop_vinfo ? LOOP_VINFO_LOOP (loop_vinfo) : NULL;
+ tree fndecl, new_temp, def;
+ gimple def_stmt;
+ gimple new_stmt = NULL;
+ int ncopies, j;
+ vec<simd_call_arg_info> arginfo = vNULL;
+ vec<tree> vargs = vNULL;
+ size_t i, nargs;
+ tree lhs, rtype, ratype;
+ vec<constructor_elt, va_gc> *ret_ctor_elts;
+
+ /* Is STMT a vectorizable call? */
+ if (!is_gimple_call (stmt))
+ return false;
+
+ fndecl = gimple_call_fndecl (stmt);
+ if (fndecl == NULL_TREE)
+ return false;
+
+ struct cgraph_node *node = cgraph_get_node (fndecl);
+ if (node == NULL || node->simd_clones == NULL)
+ return false;
+
+ if (!STMT_VINFO_RELEVANT_P (stmt_info) && !bb_vinfo)
+ return false;
+
+ if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def)
+ return false;
+
+ if (gimple_call_lhs (stmt)
+ && TREE_CODE (gimple_call_lhs (stmt)) != SSA_NAME)
+ return false;
+
+ gcc_checking_assert (!stmt_can_throw_internal (stmt));
+
+ vectype = STMT_VINFO_VECTYPE (stmt_info);
+
+ if (loop_vinfo && nested_in_vect_loop_p (loop, stmt))
+ return false;
+
+ /* FORNOW */
+ if (slp_node || PURE_SLP_STMT (stmt_info))
+ return false;
+
+ /* Process function arguments. */
+ nargs = gimple_call_num_args (stmt);
+
+ /* Bail out if the function has zero arguments. */
+ if (nargs == 0)
+ return false;
+
+ arginfo.create (nargs);
+
+ for (i = 0; i < nargs; i++)
+ {
+ simd_call_arg_info thisarginfo;
+ affine_iv iv;
+
+ thisarginfo.linear_step = 0;
+ thisarginfo.align = 0;
+ thisarginfo.op = NULL_TREE;
+
+ op = gimple_call_arg (stmt, i);
+ if (!vect_is_simple_use_1 (op, stmt, loop_vinfo, bb_vinfo,
+ &def_stmt, &def, &thisarginfo.dt,
+ &thisarginfo.vectype)
+ || thisarginfo.dt == vect_uninitialized_def)
+ {
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "use not simple.\n");
+ arginfo.release ();
+ return false;
+ }
+
+ if (thisarginfo.dt == vect_constant_def
+ || thisarginfo.dt == vect_external_def)
+ gcc_assert (thisarginfo.vectype == NULL_TREE);
+ else
+ gcc_assert (thisarginfo.vectype != NULL_TREE);
+
+ if (thisarginfo.dt != vect_constant_def
+ && thisarginfo.dt != vect_external_def
+ && loop_vinfo
+ && TREE_CODE (op) == SSA_NAME
+ && simple_iv (loop, loop_containing_stmt (stmt), op, &iv, false)
+ && tree_fits_shwi_p (iv.step))
+ {
+ thisarginfo.linear_step = tree_to_shwi (iv.step);
+ thisarginfo.op = iv.base;
+ }
+ else if ((thisarginfo.dt == vect_constant_def
+ || thisarginfo.dt == vect_external_def)
+ && POINTER_TYPE_P (TREE_TYPE (op)))
+ thisarginfo.align = get_pointer_alignment (op) / BITS_PER_UNIT;
+
+ arginfo.quick_push (thisarginfo);
+ }
+
+ unsigned int badness = 0;
+ struct cgraph_node *bestn = NULL;
+ if (STMT_VINFO_SIMD_CLONE_FNDECL (stmt_info))
+ bestn = cgraph_get_node (STMT_VINFO_SIMD_CLONE_FNDECL (stmt_info));
+ else
+ for (struct cgraph_node *n = node->simd_clones; n != NULL;
+ n = n->simdclone->next_clone)
+ {
+ unsigned int this_badness = 0;
+ if (n->simdclone->simdlen
+ > (unsigned) LOOP_VINFO_VECT_FACTOR (loop_vinfo)
+ || n->simdclone->nargs != nargs)
+ continue;
+ if (n->simdclone->simdlen
+ < (unsigned) LOOP_VINFO_VECT_FACTOR (loop_vinfo))
+ this_badness += (exact_log2 (LOOP_VINFO_VECT_FACTOR (loop_vinfo))
+ - exact_log2 (n->simdclone->simdlen)) * 1024;
+ if (n->simdclone->inbranch)
+ this_badness += 2048;
+ int target_badness = targetm.simd_clone.usable (n);
+ if (target_badness < 0)
+ continue;
+ this_badness += target_badness * 512;
+ /* FORNOW: Have to add code to add the mask argument. */
+ if (n->simdclone->inbranch)
+ continue;
+ for (i = 0; i < nargs; i++)
+ {
+ switch (n->simdclone->args[i].arg_type)
+ {
+ case SIMD_CLONE_ARG_TYPE_VECTOR:
+ if (!useless_type_conversion_p
+ (n->simdclone->args[i].orig_type,
+ TREE_TYPE (gimple_call_arg (stmt, i))))
+ i = -1;
+ else if (arginfo[i].dt == vect_constant_def
+ || arginfo[i].dt == vect_external_def
+ || arginfo[i].linear_step)
+ this_badness += 64;
+ break;
+ case SIMD_CLONE_ARG_TYPE_UNIFORM:
+ if (arginfo[i].dt != vect_constant_def
+ && arginfo[i].dt != vect_external_def)
+ i = -1;
+ break;
+ case SIMD_CLONE_ARG_TYPE_LINEAR_CONSTANT_STEP:
+ if (arginfo[i].dt == vect_constant_def
+ || arginfo[i].dt == vect_external_def
+ || (arginfo[i].linear_step
+ != n->simdclone->args[i].linear_step))
+ i = -1;
+ break;
+ case SIMD_CLONE_ARG_TYPE_LINEAR_VARIABLE_STEP:
+ /* FORNOW */
+ i = -1;
+ break;
+ case SIMD_CLONE_ARG_TYPE_MASK:
+ gcc_unreachable ();
+ }
+ if (i == (size_t) -1)
+ break;
+ if (n->simdclone->args[i].alignment > arginfo[i].align)
+ {
+ i = -1;
+ break;
+ }
+ if (arginfo[i].align)
+ this_badness += (exact_log2 (arginfo[i].align)
+ - exact_log2 (n->simdclone->args[i].alignment));
+ }
+ if (i == (size_t) -1)
+ continue;
+ if (bestn == NULL || this_badness < badness)
+ {
+ bestn = n;
+ badness = this_badness;
+ }
+ }
+
+ if (bestn == NULL)
+ {
+ arginfo.release ();
+ return false;
+ }
+
+ for (i = 0; i < nargs; i++)
+ if ((arginfo[i].dt == vect_constant_def
+ || arginfo[i].dt == vect_external_def)
+ && bestn->simdclone->args[i].arg_type == SIMD_CLONE_ARG_TYPE_VECTOR)
+ {
+ arginfo[i].vectype
+ = get_vectype_for_scalar_type (TREE_TYPE (gimple_call_arg (stmt,
+ i)));
+ if (arginfo[i].vectype == NULL
+ || (TYPE_VECTOR_SUBPARTS (arginfo[i].vectype)
+ > bestn->simdclone->simdlen))
+ {
+ arginfo.release ();
+ return false;
+ }
+ }
+
+ fndecl = bestn->decl;
+ nunits = bestn->simdclone->simdlen;
+ ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits;
+
+ /* If the function isn't const, only allow it in simd loops where user
+ has asserted that at least nunits consecutive iterations can be
+ performed using SIMD instructions. */
+ if ((loop == NULL || (unsigned) loop->safelen < nunits)
+ && gimple_vuse (stmt))
+ {
+ arginfo.release ();
+ return false;
+ }
+
+ /* Sanity check: make sure that at least one copy of the vectorized stmt
+ needs to be generated. */
+ gcc_assert (ncopies >= 1);
+
+ if (!vec_stmt) /* transformation not required. */
+ {
+ STMT_VINFO_SIMD_CLONE_FNDECL (stmt_info) = bestn->decl;
+ STMT_VINFO_TYPE (stmt_info) = call_simd_clone_vec_info_type;
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "=== vectorizable_simd_clone_call ===\n");
+/* vect_model_simple_cost (stmt_info, ncopies, dt, NULL, NULL); */
+ arginfo.release ();
+ return true;
+ }
+
+ /** Transform. **/
+
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_NOTE, vect_location, "transform call.\n");
+
+ /* Handle def. */
+ scalar_dest = gimple_call_lhs (stmt);
+ vec_dest = NULL_TREE;
+ rtype = NULL_TREE;
+ ratype = NULL_TREE;
+ if (scalar_dest)
+ {
+ vec_dest = vect_create_destination_var (scalar_dest, vectype);
+ rtype = TREE_TYPE (TREE_TYPE (fndecl));
+ if (TREE_CODE (rtype) == ARRAY_TYPE)
+ {
+ ratype = rtype;
+ rtype = TREE_TYPE (ratype);
+ }
+ }
+
+ prev_stmt_info = NULL;
+ for (j = 0; j < ncopies; ++j)
+ {
+ /* Build argument list for the vectorized call. */
+ if (j == 0)
+ vargs.create (nargs);
+ else
+ vargs.truncate (0);
+
+ for (i = 0; i < nargs; i++)
+ {
+ unsigned int k, l, m, o;
+ tree atype;
+ op = gimple_call_arg (stmt, i);
+ switch (bestn->simdclone->args[i].arg_type)
+ {
+ case SIMD_CLONE_ARG_TYPE_VECTOR:
+ atype = bestn->simdclone->args[i].vector_type;
+ o = nunits / TYPE_VECTOR_SUBPARTS (atype);
+ for (m = j * o; m < (j + 1) * o; m++)
+ {
+ if (TYPE_VECTOR_SUBPARTS (atype)
+ < TYPE_VECTOR_SUBPARTS (arginfo[i].vectype))
+ {
+ unsigned int prec = GET_MODE_BITSIZE (TYPE_MODE (atype));
+ k = (TYPE_VECTOR_SUBPARTS (arginfo[i].vectype)
+ / TYPE_VECTOR_SUBPARTS (atype));
+ gcc_assert ((k & (k - 1)) == 0);
+ if (m == 0)
+ vec_oprnd0
+ = vect_get_vec_def_for_operand (op, stmt, NULL);
+ else
+ {
+ vec_oprnd0 = arginfo[i].op;
+ if ((m & (k - 1)) == 0)
+ vec_oprnd0
+ = vect_get_vec_def_for_stmt_copy (arginfo[i].dt,
+ vec_oprnd0);
+ }
+ arginfo[i].op = vec_oprnd0;
+ vec_oprnd0
+ = build3 (BIT_FIELD_REF, atype, vec_oprnd0,
+ size_int (prec),
+ bitsize_int ((m & (k - 1)) * prec));
+ new_stmt
+ = gimple_build_assign (make_ssa_name (atype, NULL),
+ vec_oprnd0);
+ vect_finish_stmt_generation (stmt, new_stmt, gsi);
+ vargs.safe_push (gimple_assign_lhs (new_stmt));
+ }
+ else
+ {
+ k = (TYPE_VECTOR_SUBPARTS (atype)
+ / TYPE_VECTOR_SUBPARTS (arginfo[i].vectype));
+ gcc_assert ((k & (k - 1)) == 0);
+ vec<constructor_elt, va_gc> *ctor_elts;
+ if (k != 1)
+ vec_alloc (ctor_elts, k);
+ else
+ ctor_elts = NULL;
+ for (l = 0; l < k; l++)
+ {
+ if (m == 0 && l == 0)
+ vec_oprnd0
+ = vect_get_vec_def_for_operand (op, stmt, NULL);
+ else
+ vec_oprnd0
+ = vect_get_vec_def_for_stmt_copy (arginfo[i].dt,
+ arginfo[i].op);
+ arginfo[i].op = vec_oprnd0;
+ if (k == 1)
+ break;
+ CONSTRUCTOR_APPEND_ELT (ctor_elts, NULL_TREE,
+ vec_oprnd0);
+ }
+ if (k == 1)
+ vargs.safe_push (vec_oprnd0);
+ else
+ {
+ vec_oprnd0 = build_constructor (atype, ctor_elts);
+ new_stmt
+ = gimple_build_assign (make_ssa_name (atype, NULL),
+ vec_oprnd0);
+ vect_finish_stmt_generation (stmt, new_stmt, gsi);
+ vargs.safe_push (gimple_assign_lhs (new_stmt));
+ }
+ }
+ }
+ break;
+ case SIMD_CLONE_ARG_TYPE_UNIFORM:
+ vargs.safe_push (op);
+ break;
+ case SIMD_CLONE_ARG_TYPE_LINEAR_CONSTANT_STEP:
+ if (j == 0)
+ {
+ gimple_seq stmts;
+ arginfo[i].op
+ = force_gimple_operand (arginfo[i].op, &stmts, true,
+ NULL_TREE);
+ if (stmts != NULL)
+ {
+ basic_block new_bb;
+ edge pe = loop_preheader_edge (loop);
+ new_bb = gsi_insert_seq_on_edge_immediate (pe, stmts);
+ gcc_assert (!new_bb);
+ }
+ tree phi_res = copy_ssa_name (op, NULL);
+ gimple new_phi = create_phi_node (phi_res, loop->header);
+ set_vinfo_for_stmt (new_phi,
+ new_stmt_vec_info (new_phi, loop_vinfo,
+ NULL));
+ add_phi_arg (new_phi, arginfo[i].op,
+ loop_preheader_edge (loop), UNKNOWN_LOCATION);
+ enum tree_code code
+ = POINTER_TYPE_P (TREE_TYPE (op))
+ ? POINTER_PLUS_EXPR : PLUS_EXPR;
+ tree type = POINTER_TYPE_P (TREE_TYPE (op))
+ ? sizetype : TREE_TYPE (op);
+ widest_int cst
+ = wi::mul (bestn->simdclone->args[i].linear_step,
+ ncopies * nunits);
+ tree tcst = wide_int_to_tree (type, cst);
+ tree phi_arg = copy_ssa_name (op, NULL);
+ new_stmt = gimple_build_assign_with_ops (code, phi_arg,
+ phi_res, tcst);
+ gimple_stmt_iterator si = gsi_after_labels (loop->header);
+ gsi_insert_after (&si, new_stmt, GSI_NEW_STMT);
+ set_vinfo_for_stmt (new_stmt,
+ new_stmt_vec_info (new_stmt, loop_vinfo,
+ NULL));
+ add_phi_arg (new_phi, phi_arg, loop_latch_edge (loop),
+ UNKNOWN_LOCATION);
+ arginfo[i].op = phi_res;
+ vargs.safe_push (phi_res);
+ }
+ else
+ {
+ enum tree_code code
+ = POINTER_TYPE_P (TREE_TYPE (op))
+ ? POINTER_PLUS_EXPR : PLUS_EXPR;
+ tree type = POINTER_TYPE_P (TREE_TYPE (op))
+ ? sizetype : TREE_TYPE (op);
+ widest_int cst
+ = wi::mul (bestn->simdclone->args[i].linear_step,
+ j * nunits);
+ tree tcst = wide_int_to_tree (type, cst);
+ new_temp = make_ssa_name (TREE_TYPE (op), NULL);
+ new_stmt
+ = gimple_build_assign_with_ops (code, new_temp,
+ arginfo[i].op, tcst);
+ vect_finish_stmt_generation (stmt, new_stmt, gsi);
+ vargs.safe_push (new_temp);
+ }
+ break;
+ case SIMD_CLONE_ARG_TYPE_LINEAR_VARIABLE_STEP:
+ default:
+ gcc_unreachable ();
+ }
+ }
+
+ new_stmt = gimple_build_call_vec (fndecl, vargs);
+ if (vec_dest)
+ {
+ gcc_assert (ratype || TYPE_VECTOR_SUBPARTS (rtype) == nunits);
+ if (ratype)
+ new_temp = create_tmp_var (ratype, NULL);
+ else if (TYPE_VECTOR_SUBPARTS (vectype)
+ == TYPE_VECTOR_SUBPARTS (rtype))
+ new_temp = make_ssa_name (vec_dest, new_stmt);
+ else
+ new_temp = make_ssa_name (rtype, new_stmt);
+ gimple_call_set_lhs (new_stmt, new_temp);
+ }
+ vect_finish_stmt_generation (stmt, new_stmt, gsi);
+
+ if (vec_dest)
+ {
+ if (TYPE_VECTOR_SUBPARTS (vectype) < nunits)
+ {
+ unsigned int k, l;
+ unsigned int prec = GET_MODE_BITSIZE (TYPE_MODE (vectype));
+ k = nunits / TYPE_VECTOR_SUBPARTS (vectype);
+ gcc_assert ((k & (k - 1)) == 0);
+ for (l = 0; l < k; l++)
+ {
+ tree t;
+ if (ratype)
+ {
+ t = build_fold_addr_expr (new_temp);
+ t = build2 (MEM_REF, vectype, t,
+ build_int_cst (TREE_TYPE (t),
+ l * prec / BITS_PER_UNIT));
+ }
+ else
+ t = build3 (BIT_FIELD_REF, vectype, new_temp,
+ size_int (prec), bitsize_int (l * prec));
+ new_stmt
+ = gimple_build_assign (make_ssa_name (vectype, NULL), t);
+ vect_finish_stmt_generation (stmt, new_stmt, gsi);
+ if (j == 0 && l == 0)
+ STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt;
+ else
+ STMT_VINFO_RELATED_STMT (prev_stmt_info) = new_stmt;
+
+ prev_stmt_info = vinfo_for_stmt (new_stmt);
+ }
+
+ if (ratype)
+ {
+ tree clobber = build_constructor (ratype, NULL);
+ TREE_THIS_VOLATILE (clobber) = 1;
+ new_stmt = gimple_build_assign (new_temp, clobber);
+ vect_finish_stmt_generation (stmt, new_stmt, gsi);
+ }
+ continue;
+ }
+ else if (TYPE_VECTOR_SUBPARTS (vectype) > nunits)
+ {
+ unsigned int k = (TYPE_VECTOR_SUBPARTS (vectype)
+ / TYPE_VECTOR_SUBPARTS (rtype));
+ gcc_assert ((k & (k - 1)) == 0);
+ if ((j & (k - 1)) == 0)
+ vec_alloc (ret_ctor_elts, k);
+ if (ratype)
+ {
+ unsigned int m, o = nunits / TYPE_VECTOR_SUBPARTS (rtype);
+ for (m = 0; m < o; m++)
+ {
+ tree tem = build4 (ARRAY_REF, rtype, new_temp,
+ size_int (m), NULL_TREE, NULL_TREE);
+ new_stmt
+ = gimple_build_assign (make_ssa_name (rtype, NULL),
+ tem);
+ vect_finish_stmt_generation (stmt, new_stmt, gsi);
+ CONSTRUCTOR_APPEND_ELT (ret_ctor_elts, NULL_TREE,
+ gimple_assign_lhs (new_stmt));
+ }
+ tree clobber = build_constructor (ratype, NULL);
+ TREE_THIS_VOLATILE (clobber) = 1;
+ new_stmt = gimple_build_assign (new_temp, clobber);
+ vect_finish_stmt_generation (stmt, new_stmt, gsi);
+ }
+ else
+ CONSTRUCTOR_APPEND_ELT (ret_ctor_elts, NULL_TREE, new_temp);
+ if ((j & (k - 1)) != k - 1)
+ continue;
+ vec_oprnd0 = build_constructor (vectype, ret_ctor_elts);
+ new_stmt
+ = gimple_build_assign (make_ssa_name (vec_dest, NULL),
+ vec_oprnd0);
+ vect_finish_stmt_generation (stmt, new_stmt, gsi);
+
+ if ((unsigned) j == k - 1)
+ STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt;
+ else
+ STMT_VINFO_RELATED_STMT (prev_stmt_info) = new_stmt;
+
+ prev_stmt_info = vinfo_for_stmt (new_stmt);
+ continue;
+ }
+ else if (ratype)
+ {
+ tree t = build_fold_addr_expr (new_temp);
+ t = build2 (MEM_REF, vectype, t,
+ build_int_cst (TREE_TYPE (t), 0));
+ new_stmt
+ = gimple_build_assign (make_ssa_name (vec_dest, NULL), t);
+ vect_finish_stmt_generation (stmt, new_stmt, gsi);
+ tree clobber = build_constructor (ratype, NULL);
+ TREE_THIS_VOLATILE (clobber) = 1;
+ vect_finish_stmt_generation (stmt,
+ gimple_build_assign (new_temp,
+ clobber), gsi);
+ }
+ }
+
+ if (j == 0)
+ STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt;
+ else
+ STMT_VINFO_RELATED_STMT (prev_stmt_info) = new_stmt;
+
+ prev_stmt_info = vinfo_for_stmt (new_stmt);
+ }
+
+ vargs.release ();
+
+ /* The call in STMT might prevent it from being removed in dce.
+ We however cannot remove it here, due to the way the ssa name
+ it defines is mapped to the new definition. So just replace
+ rhs of the statement with something harmless. */
+
+ if (slp_node)
+ return true;
+
+ if (scalar_dest)
+ {
+ type = TREE_TYPE (scalar_dest);
+ if (is_pattern_stmt_p (stmt_info))
+ lhs = gimple_call_lhs (STMT_VINFO_RELATED_STMT (stmt_info));
+ else
+ lhs = gimple_call_lhs (stmt);
+ new_stmt = gimple_build_assign (lhs, build_zero_cst (type));
+ }
+ else
+ new_stmt = gimple_build_nop ();
+ set_vinfo_for_stmt (new_stmt, stmt_info);
+ set_vinfo_for_stmt (stmt, NULL);
+ STMT_VINFO_STMT (stmt_info) = new_stmt;
+ gsi_replace (gsi, new_stmt, false);
+ unlink_stmt_vdef (stmt);
+
+ return true;
+}
+
+
/* Function vect_gen_widened_results_half
Create a vector stmt whose code, type, number of arguments, and result
if (STMT_VINFO_RELEVANT_P (stmt_info))
{
gcc_assert (!VECTOR_MODE_P (TYPE_MODE (gimple_expr_type (stmt))));
- gcc_assert (STMT_VINFO_VECTYPE (stmt_info));
+ gcc_assert (STMT_VINFO_VECTYPE (stmt_info)
+ || (is_gimple_call (stmt)
+ && gimple_call_lhs (stmt) == NULL_TREE));
*need_to_vectorize = true;
}
if (!bb_vinfo
&& (STMT_VINFO_RELEVANT_P (stmt_info)
|| STMT_VINFO_DEF_TYPE (stmt_info) == vect_reduction_def))
- ok = (vectorizable_conversion (stmt, NULL, NULL, NULL)
+ ok = (vectorizable_simd_clone_call (stmt, NULL, NULL, NULL)
+ || vectorizable_conversion (stmt, NULL, NULL, NULL)
|| vectorizable_shift (stmt, NULL, NULL, NULL)
|| vectorizable_operation (stmt, NULL, NULL, NULL)
|| vectorizable_assignment (stmt, NULL, NULL, NULL)
else
{
if (bb_vinfo)
- ok = (vectorizable_conversion (stmt, NULL, NULL, node)
+ ok = (vectorizable_simd_clone_call (stmt, NULL, NULL, node)
+ || vectorizable_conversion (stmt, NULL, NULL, node)
|| vectorizable_shift (stmt, NULL, NULL, node)
|| vectorizable_operation (stmt, NULL, NULL, node)
|| vectorizable_assignment (stmt, NULL, NULL, node)
stmt = gsi_stmt (*gsi);
break;
+ case call_simd_clone_vec_info_type:
+ done = vectorizable_simd_clone_call (stmt, gsi, &vec_stmt, slp_node);
+ stmt = gsi_stmt (*gsi);
+ break;
+
case reduc_vec_info_type:
done = vectorizable_reduction (stmt, gsi, &vec_stmt, slp_node);
gcc_assert (done);
#include "coretypes.h"
#include "dumpfile.h"
#include "tm.h"
-#include "ggc.h"
#include "tree.h"
#include "stor-layout.h"
#include "tree-pretty-print.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimple-walk.h"
#include "cfgloop.h"
#include "tree-vectorizer.h"
#include "tree-pass.h"
-#include "hash-table.h"
#include "tree-ssa-propagate.h"
#include "dbgcnt.h"
shift_vec_info_type,
op_vec_info_type,
call_vec_info_type,
+ call_simd_clone_vec_info_type,
assignment_vec_info_type,
condition_vec_info_type,
reduc_vec_info_type,
of this stmt. */
vec<dr_p> same_align_refs;
+ /* Selected SIMD clone's function decl. */
+ tree simd_clone_fndecl;
+
/* Classify the def of this stmt. */
enum vect_def_type def_type;
#define STMT_VINFO_RELATED_STMT(S) (S)->related_stmt
#define STMT_VINFO_PATTERN_DEF_SEQ(S) (S)->pattern_def_seq
#define STMT_VINFO_SAME_ALIGN_REFS(S) (S)->same_align_refs
+#define STMT_VINFO_SIMD_CLONE_FNDECL(S) (S)->simd_clone_fndecl
#define STMT_VINFO_DEF_TYPE(S) (S)->def_type
#define STMT_VINFO_GROUP_FIRST_ELEMENT(S) (S)->first_element
#define STMT_VINFO_GROUP_NEXT_ELEMENT(S) (S)->next_element
/* Return true if the vect cost model is unlimited. */
static inline bool
-unlimited_cost_model ()
+unlimited_cost_model (loop_p loop)
{
- return flag_vect_cost_model == VECT_COST_MODEL_UNLIMITED;
+ if (loop != NULL && loop->force_vect
+ && flag_simd_cost_model != VECT_COST_MODEL_DEFAULT)
+ return flag_simd_cost_model == VECT_COST_MODEL_UNLIMITED;
+ return (flag_vect_cost_model == VECT_COST_MODEL_UNLIMITED);
}
/* Source location */
#include "system.h"
#include "coretypes.h"
#include "tm.h"
-#include "ggc.h"
#include "flags.h"
#include "tree.h"
#include "stor-layout.h"
#include "calls.h"
#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-fold.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimple-walk.h"
gcc_assert (min && max);
+ gcc_assert ((!TREE_OVERFLOW_P (min) || is_overflow_infinity (min))
+ && (!TREE_OVERFLOW_P (max) || is_overflow_infinity (max)));
+
if (INTEGRAL_TYPE_P (TREE_TYPE (min)) && t == VR_ANTI_RANGE)
gcc_assert (!vrp_val_is_min (min) || !vrp_val_is_max (max));
set_value_range_to_value (value_range_t *vr, tree val, bitmap equiv)
{
gcc_assert (is_gimple_min_invariant (val));
- val = avoid_overflow_infinity (val);
+ if (TREE_OVERFLOW_P (val))
+ val = drop_tree_overflow (val);
set_value_range (vr, VR_RANGE, val, val, equiv);
}
}
else if (CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (op_def)))
{
- /* Recurse through the type conversion. */
- retval |= register_edge_assert_for_1 (gimple_assign_rhs1 (op_def),
- code, e, bsi);
+ /* Recurse through the type conversion, unless it is a narrowing
+ conversion or conversion from non-integral type. */
+ tree rhs = gimple_assign_rhs1 (op_def);
+ if (INTEGRAL_TYPE_P (TREE_TYPE (rhs))
+ && (TYPE_PRECISION (TREE_TYPE (rhs))
+ <= TYPE_PRECISION (TREE_TYPE (op))))
+ retval |= register_edge_assert_for_1 (rhs, code, e, bsi);
}
return retval;
/* Try folding the statement to a constant first. */
tree tem = gimple_fold_stmt_to_constant (stmt, vrp_valueize);
- if (tem && !is_overflow_infinity (tem))
- set_value_range (&new_vr, VR_RANGE, tem, tem, NULL);
+ if (tem)
+ set_value_range_to_value (&new_vr, tem, NULL);
/* Then dispatch to value-range extracting functions. */
else if (code == GIMPLE_CALL)
extract_range_basic (&new_vr, stmt);
}
else if ((operand_less_p (vr1min, *vr0max) == 1
|| operand_equal_p (vr1min, *vr0max, 0))
- && operand_less_p (*vr0min, vr1min) == 1)
+ && operand_less_p (*vr0min, vr1min) == 1
+ && operand_less_p (*vr0max, vr1max) == 1)
{
/* [ ( ] ) or [ ]( ) */
if (*vr0type == VR_RANGE
}
else if ((operand_less_p (*vr0min, vr1max) == 1
|| operand_equal_p (*vr0min, vr1max, 0))
- && operand_less_p (vr1min, *vr0min) == 1)
+ && operand_less_p (vr1min, *vr0min) == 1
+ && operand_less_p (vr1max, *vr0max) == 1)
{
/* ( [ ) ] or ( )[ ] */
if (*vr0type == VR_RANGE
}
else
{
- if (is_overflow_infinity (arg))
+ if (TREE_OVERFLOW_P (arg))
arg = drop_tree_overflow (arg);
vr_arg.type = VR_RANGE;
#include "function.h"
#include "obstack.h"
#include "toplev.h" /* get_random_seed */
-#include "ggc.h"
#include "hashtab.h"
#include "filenames.h"
#include "output.h"
#include "tree-iterator.h"
#include "basic-block.h"
#include "bitmap.h"
+#include "pointer-set.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimplify.h"
#include "expr.h"
#include "tree-dfa.h"
#include "params.h"
-#include "pointer-set.h"
#include "tree-pass.h"
#include "langhooks-def.h"
#include "diagnostic.h"
case POINTER_TYPE:
case REFERENCE_TYPE:
- case POINTER_BOUNDS_TYPE:
- /* Cache NULL pointer and zero bounds. */
+ /* Cache NULL pointer. */
if (hwi == 0)
{
limit = 1;
switch (TREE_CODE (type))
{
case VOID_TYPE:
- case POINTER_BOUNDS_TYPE:
case COMPLEX_TYPE:
case ENUMERAL_TYPE:
case BOOLEAN_TYPE:
{
const char *file = main_input_filename;
if (! file)
- file = input_filename;
+ file = LOCATION_FILE (input_location);
/* Just use the file's basename, because the full pathname
might be quite long. */
p = q = ASTRDUP (lbasename (file));
if (! name)
name = "";
if (! file)
- file = input_filename;
+ file = LOCATION_FILE (input_location);
len = strlen (file);
q = (char *) alloca (9 + 17 + len + 1);
during initialization of data types to create the 5 basic atomic
types. The generic build_variant_type function requires these to
already be set up in order to function properly, so cannot be
- called from there. */
+ called from there. If ALIGN is non-zero, then ensure alignment is
+ overridden to this value. */
static tree
-build_atomic_base (tree type)
+build_atomic_base (tree type, unsigned int align)
{
tree t;
t = build_variant_type_copy (type);
set_type_quals (t, TYPE_QUAL_ATOMIC);
+ if (align)
+ TYPE_ALIGN (t) = align;
+
return t;
}
/* Don't call build_qualified type for atomics. That routine does
special processing for atomics, and until they are initialized
- it's better not to make that call. */
-
- atomicQI_type_node = build_atomic_base (unsigned_intQI_type_node);
- atomicHI_type_node = build_atomic_base (unsigned_intHI_type_node);
- atomicSI_type_node = build_atomic_base (unsigned_intSI_type_node);
- atomicDI_type_node = build_atomic_base (unsigned_intDI_type_node);
- atomicTI_type_node = build_atomic_base (unsigned_intTI_type_node);
-
+ it's better not to make that call.
+
+ Check to see if there is a target override for atomic types. */
+
+ atomicQI_type_node = build_atomic_base (unsigned_intQI_type_node,
+ targetm.atomic_align_for_mode (QImode));
+ atomicHI_type_node = build_atomic_base (unsigned_intHI_type_node,
+ targetm.atomic_align_for_mode (HImode));
+ atomicSI_type_node = build_atomic_base (unsigned_intSI_type_node,
+ targetm.atomic_align_for_mode (SImode));
+ atomicDI_type_node = build_atomic_base (unsigned_intDI_type_node,
+ targetm.atomic_align_for_mode (DImode));
+ atomicTI_type_node = build_atomic_base (unsigned_intTI_type_node,
+ targetm.atomic_align_for_mode (TImode));
+
access_public_node = get_identifier ("public");
access_protected_node = get_identifier ("protected");
access_private_node = get_identifier ("private");
void_type_node = make_node (VOID_TYPE);
layout_type (void_type_node);
- pointer_bounds_type_node = targetm.chkp_bound_type ();
-
/* We are not going to have real types in C with less than byte alignment,
so we might as well not have any types that claim to have it. */
TYPE_ALIGN (void_type_node) = BITS_PER_UNIT;
/* The void type in C */
DEFTREECODE (VOID_TYPE, "void_type", tcc_type, 0)
-/* Type to hold bounds for a pointer.
- Has TYPE_PRECISION component to specify number of bits used
- by this type. */
-DEFTREECODE (POINTER_BOUNDS_TYPE, "pointer_bounds_type", tcc_type, 0)
-
/* Type of functions. Special fields:
TREE_TYPE type of value returned.
TYPE_ARG_TYPES list of types of arguments expected.
/* Nonzero if this type is a complete type. */
#define COMPLETE_TYPE_P(NODE) (TYPE_SIZE (NODE) != NULL_TREE)
-/* Nonzero if this type is a pointer bounds type. */
-#define POINTER_BOUNDS_TYPE_P(NODE) \
- (TREE_CODE (NODE) == POINTER_BOUNDS_TYPE)
-
-/* Nonzero if this node has a pointer bounds type. */
-#define POINTER_BOUNDS_P(NODE) \
- (POINTER_BOUNDS_TYPE_P (TREE_TYPE (NODE)))
-
-/* Nonzero if this type supposes bounds existence. */
-#define BOUNDED_TYPE_P(type) (POINTER_TYPE_P (type))
-
-/* Nonzero for objects with bounded type. */
-#define BOUNDED_P(node) \
- BOUNDED_TYPE_P (TREE_TYPE (node))
-
/* Nonzero if this type is the (possibly qualified) void type. */
#define VOID_TYPE_P(NODE) (TREE_CODE (NODE) == VOID_TYPE)
#define CALL_ALLOCA_FOR_VAR_P(NODE) \
(CALL_EXPR_CHECK (NODE)->base.protected_flag)
-/* In a CALL_EXPR, means call was instrumented by Pointer Bounds Checker. */
-#define CALL_WITH_BOUNDS_P(NODE) (CALL_EXPR_CHECK (NODE)->base.deprecated_flag)
-
/* In a type, nonzero means that all objects of the type are guaranteed by the
language or front-end to be properly aligned, so we can indicate that a MEM
of this type is aligned at least to the alignment of the type, even if it
!= UNKNOWN_LOCATION)
/* The location to be used in a diagnostic about this expression. Do not
use this macro if the location will be assigned to other expressions. */
-#define EXPR_LOC_OR_HERE(NODE) (EXPR_HAS_LOCATION (NODE) \
- ? (NODE)->exp.locus : input_location)
#define EXPR_LOC_OR_LOC(NODE, LOCUS) (EXPR_HAS_LOCATION (NODE) \
? (NODE)->exp.locus : (LOCUS))
#define EXPR_FILENAME(NODE) LOCATION_FILE (EXPR_CHECK ((NODE))->exp.locus)
#define OMP_CLAUSE_LINEAR_NO_COPYOUT(NODE) \
TREE_PRIVATE (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_LINEAR))
+/* True if a LINEAR clause has a stride that is variable. */
+#define OMP_CLAUSE_LINEAR_VARIABLE_STRIDE(NODE) \
+ TREE_PROTECTED (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_LINEAR))
+
#define OMP_CLAUSE_LINEAR_STEP(NODE) \
OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_LINEAR), 1)
#define complex_double_type_node global_trees[TI_COMPLEX_DOUBLE_TYPE]
#define complex_long_double_type_node global_trees[TI_COMPLEX_LONG_DOUBLE_TYPE]
-#define pointer_bounds_type_node global_trees[TI_POINTER_BOUNDS_TYPE]
-
#define void_type_node global_trees[TI_VOID_TYPE]
/* The C type `void *'. */
#define ptr_type_node global_trees[TI_PTR_TYPE]
#include "intl.h"
#include "tm.h"
#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimplify.h"
#include "gimple-iterator.h"
#include "stringpool.h"
#include "cgraph.h"
#include "tree-pass.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "gimple-walk.h"
#include "hashtab.h"
-#include "pointer-set.h"
#include "output.h"
#include "tm_p.h"
#include "toplev.h"
build_index_type (size_int (len)));
TREE_READONLY (str) = 1;
TREE_STATIC (str) = 1;
- str = build_fold_addr_expr_loc (loc, str);
+ str = build_fold_addr_expr (str);
tree ctor = build_constructor_va (type, 3, NULL_TREE, str, NULL_TREE,
build_int_cst (unsigned_type_node,
xloc.line), NULL_TREE,
type = TYPE_MAIN_VARIANT (type);
tree decl = decl_for_type_lookup (type);
- if (decl != NULL_TREE)
- return decl;
+ /* It is possible that some of the earlier created DECLs were found
+ unused, in that case they weren't emitted and varpool_get_node
+ returns NULL node on them. But now we really need them. Thus,
+ renew them here. */
+ if (decl != NULL_TREE && varpool_get_node (decl))
+ return build_fold_addr_expr (decl);
tree dtype = ubsan_type_descriptor_type ();
tree type2 = type;
DECL_INITIAL (decl) = ctor;
rest_of_decl_compilation (decl, 1, 0);
- /* Save the address of the VAR_DECL into the hash table. */
- decl = build_fold_addr_expr (decl);
+ /* Save the VAR_DECL into the hash table. */
decl_for_type_insert (type, decl);
- return decl;
+ return build_fold_addr_expr (decl);
}
/* Create a structure for the ubsan library. NAME is a name of the new
{
va_list args;
tree ret, t;
- tree fields[3];
+ tree fields[5];
vec<tree, va_gc> *saved_args = NULL;
size_t i = 0;
tree td_type = ubsan_type_descriptor_type ();
TYPE_READONLY (td_type) = 1;
td_type = build_pointer_type (td_type);
+ loc = LOCATION_LOCUS (loc);
/* Create the structure type. */
ret = make_node (RECORD_TYPE);
{
/* We have to add two more decls. */
fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
- pointer_sized_int_node);
+ pointer_sized_int_node);
DECL_CONTEXT (fields[i]) = ret;
DECL_CHAIN (fields[i - 1]) = fields[i];
i++;
gsi_insert_before (iter, g, GSI_SAME_STMT);
}
-/* Callback function for the pointer instrumentation. */
+/* Perform the pointer instrumentation. */
-static tree
-instrument_null (tree *tp, int * /*walk_subtree*/, void *data)
+static void
+instrument_null (gimple_stmt_iterator gsi, bool is_lhs)
{
- tree t = *tp;
+ gimple stmt = gsi_stmt (gsi);
+ tree t = is_lhs ? gimple_get_lhs (stmt) : gimple_assign_rhs1 (stmt);
+ t = get_base_address (t);
const enum tree_code code = TREE_CODE (t);
- struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
-
if (code == MEM_REF
&& TREE_CODE (TREE_OPERAND (t, 0)) == SSA_NAME)
- instrument_mem_ref (TREE_OPERAND (t, 0), &wi->gsi, wi->is_lhs);
+ instrument_mem_ref (TREE_OPERAND (t, 0), &gsi, is_lhs);
else if (code == ADDR_EXPR
&& POINTER_TYPE_P (TREE_TYPE (t))
&& TREE_CODE (TREE_TYPE (TREE_TYPE (t))) == METHOD_TYPE)
- instrument_member_call (&wi->gsi);
-
- return NULL_TREE;
+ instrument_member_call (&gsi);
}
/* Gate and execute functions for ubsan pass. */
{
for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
{
- struct walk_stmt_info wi;
gimple stmt = gsi_stmt (gsi);
- if (is_gimple_debug (stmt))
+ if (is_gimple_debug (stmt) || gimple_clobber_p (stmt))
{
gsi_next (&gsi);
continue;
}
- memset (&wi, 0, sizeof (wi));
- wi.gsi = gsi;
- walk_gimple_op (stmt, instrument_null, &wi);
+ if (flag_sanitize & SANITIZE_NULL)
+ {
+ if (gimple_store_p (stmt))
+ instrument_null (gsi, true);
+ if (gimple_assign_load_p (stmt))
+ instrument_null (gsi, false);
+ }
+
gsi_next (&gsi);
}
}
#include "recog.h"
#include "optabs.h"
#include "regs.h"
-#include "ggc.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimplify.h"
#include "gimple-iterator.h"
#include "gcov-io.h"
#include "timevar.h"
#include "dumpfile.h"
-#include "pointer-set.h"
#include "profile.h"
#include "data-streamer.h"
#include "builtins.h"
#include "tree.h"
#include "varasm.h"
#include "stor-layout.h"
-#include "gimple.h"
+#include "pointer-set.h"
+#include "hash-table.h"
+#include "basic-block.h"
#include "tm_p.h"
#include "hard-reg-set.h"
-#include "basic-block.h"
#include "flags.h"
#include "insn-config.h"
#include "reload.h"
#include "sbitmap.h"
#include "alloc-pool.h"
#include "fibheap.h"
-#include "hash-table.h"
#include "regs.h"
#include "expr.h"
#include "tree-pass.h"
#include "params.h"
#include "diagnostic.h"
#include "tree-pretty-print.h"
-#include "pointer-set.h"
#include "recog.h"
#include "tm_p.h"
#include "alias.h"
&maxsize);
if (!DECL_P (innerdecl)
|| DECL_IGNORED_P (innerdecl)
+ /* Do not track declarations for parts of tracked parameters
+ since we want to track them as a whole instead. */
+ || (TREE_CODE (innerdecl) == PARM_DECL
+ && DECL_MODE (innerdecl) != BLKmode
+ && TREE_CODE (TREE_TYPE (innerdecl)) != UNION_TYPE)
|| TREE_STATIC (innerdecl)
|| bitsize <= 0
|| bitpos + bitsize > 256
if (type != MO_VAL_SET)
goto log_and_return;
+ /* We cannot track values for multiple-part variables, so we track only
+ locations for tracked parameters passed either by invisible reference
+ or directly in multiple locations. */
+ if (track_p
+ && REG_P (loc)
+ && REG_EXPR (loc)
+ && TREE_CODE (REG_EXPR (loc)) == PARM_DECL
+ && DECL_MODE (REG_EXPR (loc)) != BLKmode
+ && ((MEM_P (DECL_INCOMING_RTL (REG_EXPR (loc)))
+ && XEXP (DECL_INCOMING_RTL (REG_EXPR (loc)), 0) != arg_pointer_rtx)
+ || (GET_CODE (DECL_INCOMING_RTL (REG_EXPR (loc))) == PARALLEL
+ && XVECLEN (DECL_INCOMING_RTL (REG_EXPR (loc)), 0) > 1)))
+ goto log_and_return;
+
v = find_use_val (oloc, mode, cui);
if (!v)
return true;
}
}
+ else if (GET_CODE (rtl) == PARALLEL)
+ {
+ tree decl = NULL_TREE;
+ HOST_WIDE_INT offset = MAX_VAR_PARTS;
+ int len = XVECLEN (rtl, 0), i;
+
+ for (i = 0; i < len; i++)
+ {
+ rtx reg = XEXP (XVECEXP (rtl, 0, i), 0);
+ if (!REG_P (reg) || !REG_ATTRS (reg))
+ break;
+ if (!decl)
+ decl = REG_EXPR (reg);
+ if (REG_EXPR (reg) != decl)
+ break;
+ if (REG_OFFSET (reg) < offset)
+ offset = REG_OFFSET (reg);
+ }
+
+ if (i == len)
+ {
+ *declp = decl;
+ *offsetp = offset;
+ return true;
+ }
+ }
else if (MEM_P (rtl))
{
if (MEM_ATTRS (rtl))
p.outgoing = incoming;
vec_safe_push (windowed_parm_regs, p);
}
+ else if (GET_CODE (incoming) == PARALLEL)
+ {
+ rtx outgoing
+ = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (XVECLEN (incoming, 0)));
+ int i;
+
+ for (i = 0; i < XVECLEN (incoming, 0); i++)
+ {
+ rtx reg = XEXP (XVECEXP (incoming, 0, i), 0);
+ parm_reg_t p;
+ p.incoming = reg;
+ reg = gen_rtx_REG_offset (reg, GET_MODE (reg),
+ OUTGOING_REGNO (REGNO (reg)), 0);
+ p.outgoing = reg;
+ XVECEXP (outgoing, 0, i)
+ = gen_rtx_EXPR_LIST (VOIDmode, reg,
+ XEXP (XVECEXP (incoming, 0, i), 1));
+ vec_safe_push (windowed_parm_regs, p);
+ }
+
+ incoming = outgoing;
+ }
else if (MEM_P (incoming)
&& REG_P (XEXP (incoming, 0))
&& HARD_REGISTER_P (XEXP (incoming, 0)))
}
}
}
+ else if (GET_CODE (incoming) == PARALLEL && !dv_onepart_p (dv))
+ {
+ int i;
+
+ for (i = 0; i < XVECLEN (incoming, 0); i++)
+ {
+ rtx reg = XEXP (XVECEXP (incoming, 0, i), 0);
+ offset = REG_OFFSET (reg);
+ gcc_assert (REGNO (reg) < FIRST_PSEUDO_REGISTER);
+ attrs_list_insert (&out->regs[REGNO (reg)], dv, offset, reg);
+ set_variable_part (out, reg, dv, offset,
+ VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
+ }
+ }
else if (MEM_P (incoming))
{
incoming = var_lowpart (mode, incoming);
case REFERENCE_TYPE:
case OFFSET_TYPE:
case FIXED_POINT_TYPE:
- case POINTER_BOUNDS_TYPE:
case NULLPTR_TYPE:
if (! assemble_integer (expand_expr (exp, NULL_RTX, VOIDmode,
EXPAND_INITIALIZER),
#include "langhooks.h"
#include "diagnostic-core.h"
#include "hashtab.h"
-#include "ggc.h"
#include "timevar.h"
#include "debug.h"
#include "target.h"
#include "output.h"
-#include "gimple.h"
+#include "gimple-expr.h"
#include "flags.h"
/* List of hooks triggered on varpool_node events. */
fprintf (f, " initialized");
if (node->output)
fprintf (f, " output");
- if (node->need_bounds_init)
- fprintf (f, " need-bounds-init");
if (TREE_READONLY (node->decl))
fprintf (f, " read-only");
if (ctor_for_folding (node->decl) != error_mark_node)
#include "coretypes.h"
#include "tree.h"
#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimple-ssa.h"
+2013-12-04 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * longlong.h: New file.
+
2013-10-29 Marc Glisse <marc.glisse@inria.fr>
PR tree-optimization/58689
+2013-11-27 Ian Lance Taylor <iant@google.com>
+
+ * dwarf.c (find_address_ranges): New static function, broken out
+ of build_address_map.
+ (build_address_map): Call it.
+ * btest.c (check): Check for missing filename or function, rather
+ than crashing.
+ (f3): Check that enough frames were returned.
+
2013-11-19 Jakub Jelinek <jakub@redhat.com>
* backtrace.h (backtrace_syminfo_callback): Add symsize argument.
{
if (*failed)
return;
+ if (all[index].filename == NULL || all[index].function == NULL)
+ {
+ fprintf (stderr, "%s: [%d]: missing file name or function name\n",
+ name, index);
+ *failed = 1;
+ return;
+ }
if (strcmp (base (all[index].filename), "btest.c") != 0)
{
fprintf (stderr, "%s: [%d]: got %s expected test.c\n", name, index,
data.failed = 1;
}
+ if (data.index < 3)
+ {
+ fprintf (stderr,
+ "test1: not enough frames; got %zu, expected at least 3\n",
+ data.index);
+ data.failed = 1;
+ }
+
check ("test1", 0, all, f3line, "f3", &data.failed);
check ("test1", 1, all, f2line, "f2", &data.failed);
check ("test1", 2, all, f1line, "test1", &data.failed);
return 1;
}
-/* Build a mapping from address ranges to the compilation units where
- the line number information for that range can be found. Returns 1
- on success, 0 on failure. */
+/* Find the address range covered by a compilation unit, reading from
+ UNIT_BUF and adding values to U. Returns 1 if all data could be
+ read, 0 if there is some error. */
static int
-build_address_map (struct backtrace_state *state, uintptr_t base_address,
- const unsigned char *dwarf_info, size_t dwarf_info_size,
- const unsigned char *dwarf_abbrev, size_t dwarf_abbrev_size,
- const unsigned char *dwarf_ranges, size_t dwarf_ranges_size,
- const unsigned char *dwarf_str, size_t dwarf_str_size,
- int is_bigendian, backtrace_error_callback error_callback,
- void *data, struct unit_addrs_vector *addrs)
+find_address_ranges (struct backtrace_state *state, uintptr_t base_address,
+ struct dwarf_buf *unit_buf,
+ const unsigned char *dwarf_str, size_t dwarf_str_size,
+ const unsigned char *dwarf_ranges,
+ size_t dwarf_ranges_size,
+ int is_bigendian, backtrace_error_callback error_callback,
+ void *data, struct unit *u,
+ struct unit_addrs_vector *addrs)
{
- struct dwarf_buf info;
- struct abbrevs abbrevs;
-
- memset (&addrs->vec, 0, sizeof addrs->vec);
- addrs->count = 0;
-
- /* Read through the .debug_info section. FIXME: Should we use the
- .debug_aranges section? gdb and addr2line don't use it, but I'm
- not sure why. */
-
- info.name = ".debug_info";
- info.start = dwarf_info;
- info.buf = dwarf_info;
- info.left = dwarf_info_size;
- info.is_bigendian = is_bigendian;
- info.error_callback = error_callback;
- info.data = data;
- info.reported_underflow = 0;
-
- memset (&abbrevs, 0, sizeof abbrevs);
- while (info.left > 0)
+ while (unit_buf->left > 0)
{
- const unsigned char *unit_data_start;
- uint64_t len;
- int is_dwarf64;
- struct dwarf_buf unit_buf;
- int version;
- uint64_t abbrev_offset;
- const struct abbrev *abbrev;
- int addrsize;
- const unsigned char *unit_data;
- size_t unit_data_len;
- size_t unit_data_offset;
uint64_t code;
- size_t i;
+ const struct abbrev *abbrev;
uint64_t lowpc;
int have_lowpc;
uint64_t highpc;
int highpc_is_relative;
uint64_t ranges;
int have_ranges;
- uint64_t lineoff;
- int have_lineoff;
- const char *filename;
- const char *comp_dir;
-
- if (info.reported_underflow)
- goto fail;
-
- unit_data_start = info.buf;
-
- is_dwarf64 = 0;
- len = read_uint32 (&info);
- if (len == 0xffffffff)
- {
- len = read_uint64 (&info);
- is_dwarf64 = 1;
- }
-
- unit_buf = info;
- unit_buf.left = len;
-
- if (!advance (&info, len))
- goto fail;
-
- version = read_uint16 (&unit_buf);
- if (version < 2 || version > 4)
- {
- dwarf_buf_error (&unit_buf, "unrecognized DWARF version");
- goto fail;
- }
-
- abbrev_offset = read_offset (&unit_buf, is_dwarf64);
- if (!read_abbrevs (state, abbrev_offset, dwarf_abbrev, dwarf_abbrev_size,
- is_bigendian, error_callback, data, &abbrevs))
- goto fail;
-
- addrsize = read_byte (&unit_buf);
-
- unit_data = unit_buf.buf;
- unit_data_len = unit_buf.left;
- unit_data_offset = unit_buf.buf - unit_data_start;
+ size_t i;
- /* We only look at the first attribute in the compilation unit.
- In practice this will be a DW_TAG_compile_unit which will
- tell us the PC range and where to find the line number
- information. */
+ code = read_uleb128 (unit_buf);
+ if (code == 0)
+ return 1;
- code = read_uleb128 (&unit_buf);
- abbrev = lookup_abbrev (&abbrevs, code, error_callback, data);
+ abbrev = lookup_abbrev (&u->abbrevs, code, error_callback, data);
if (abbrev == NULL)
- goto fail;
+ return 0;
lowpc = 0;
have_lowpc = 0;
highpc_is_relative = 0;
ranges = 0;
have_ranges = 0;
- lineoff = 0;
- have_lineoff = 0;
- filename = NULL;
- comp_dir = NULL;
for (i = 0; i < abbrev->num_attrs; ++i)
{
struct attr_val val;
- if (!read_attribute (abbrev->attrs[i].form, &unit_buf, is_dwarf64,
- version, addrsize, dwarf_str, dwarf_str_size,
- &val))
- goto fail;
+ if (!read_attribute (abbrev->attrs[i].form, unit_buf,
+ u->is_dwarf64, u->version, u->addrsize,
+ dwarf_str, dwarf_str_size, &val))
+ return 0;
switch (abbrev->attrs[i].name)
{
have_lowpc = 1;
}
break;
+
case DW_AT_high_pc:
if (val.encoding == ATTR_VAL_ADDRESS)
{
highpc_is_relative = 1;
}
break;
+
case DW_AT_ranges:
if (val.encoding == ATTR_VAL_UINT
|| val.encoding == ATTR_VAL_REF_SECTION)
have_ranges = 1;
}
break;
+
case DW_AT_stmt_list:
- if (val.encoding == ATTR_VAL_UINT
- || val.encoding == ATTR_VAL_REF_SECTION)
- {
- lineoff = val.u.uint;
- have_lineoff = 1;
- }
+ if (abbrev->tag == DW_TAG_compile_unit
+ && (val.encoding == ATTR_VAL_UINT
+ || val.encoding == ATTR_VAL_REF_SECTION))
+ u->lineoff = val.u.uint;
break;
+
case DW_AT_name:
- if (val.encoding == ATTR_VAL_STRING)
- filename = val.u.string;
+ if (abbrev->tag == DW_TAG_compile_unit
+ && val.encoding == ATTR_VAL_STRING)
+ u->filename = val.u.string;
break;
+
case DW_AT_comp_dir:
- if (val.encoding == ATTR_VAL_STRING)
- comp_dir = val.u.string;
+ if (abbrev->tag == DW_TAG_compile_unit
+ && val.encoding == ATTR_VAL_STRING)
+ u->comp_dir = val.u.string;
break;
+
default:
break;
}
}
- if (unit_buf.reported_underflow)
- goto fail;
-
- if (((have_lowpc && have_highpc) || have_ranges) && have_lineoff)
+ if (abbrev->tag == DW_TAG_compile_unit
+ || abbrev->tag == DW_TAG_subprogram)
{
- struct unit *u;
- struct unit_addrs a;
-
- u = ((struct unit *)
- backtrace_alloc (state, sizeof *u, error_callback, data));
- if (u == NULL)
- goto fail;
- u->unit_data = unit_data;
- u->unit_data_len = unit_data_len;
- u->unit_data_offset = unit_data_offset;
- u->version = version;
- u->is_dwarf64 = is_dwarf64;
- u->addrsize = addrsize;
- u->filename = filename;
- u->comp_dir = comp_dir;
- u->abs_filename = NULL;
- u->lineoff = lineoff;
- u->abbrevs = abbrevs;
- memset (&abbrevs, 0, sizeof abbrevs);
-
- /* The actual line number mappings will be read as
- needed. */
- u->lines = NULL;
- u->lines_count = 0;
- u->function_addrs = NULL;
- u->function_addrs_count = 0;
-
if (have_ranges)
{
if (!add_unit_ranges (state, base_address, u, ranges, lowpc,
is_bigendian, dwarf_ranges,
- dwarf_ranges_size, error_callback, data,
- addrs))
- {
- free_abbrevs (state, &u->abbrevs, error_callback, data);
- backtrace_free (state, u, sizeof *u, error_callback, data);
- goto fail;
- }
+ dwarf_ranges_size, error_callback,
+ data, addrs))
+ return 0;
}
- else
+ else if (have_lowpc && have_highpc)
{
+ struct unit_addrs a;
+
if (highpc_is_relative)
highpc += lowpc;
a.low = lowpc;
if (!add_unit_addr (state, base_address, a, error_callback, data,
addrs))
- {
- free_abbrevs (state, &u->abbrevs, error_callback, data);
- backtrace_free (state, u, sizeof *u, error_callback, data);
- goto fail;
- }
+ return 0;
}
+
+ /* If we found the PC range in the DW_TAG_compile_unit, we
+ can stop now. */
+ if (abbrev->tag == DW_TAG_compile_unit
+ && (have_ranges || (have_lowpc && have_highpc)))
+ return 1;
}
- else
+
+ if (abbrev->has_children)
{
- free_abbrevs (state, &abbrevs, error_callback, data);
- memset (&abbrevs, 0, sizeof abbrevs);
+ if (!find_address_ranges (state, base_address, unit_buf,
+ dwarf_str, dwarf_str_size,
+ dwarf_ranges, dwarf_ranges_size,
+ is_bigendian, error_callback, data,
+ u, addrs))
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+/* Build a mapping from address ranges to the compilation units where
+ the line number information for that range can be found. Returns 1
+ on success, 0 on failure. */
+
+static int
+build_address_map (struct backtrace_state *state, uintptr_t base_address,
+ const unsigned char *dwarf_info, size_t dwarf_info_size,
+ const unsigned char *dwarf_abbrev, size_t dwarf_abbrev_size,
+ const unsigned char *dwarf_ranges, size_t dwarf_ranges_size,
+ const unsigned char *dwarf_str, size_t dwarf_str_size,
+ int is_bigendian, backtrace_error_callback error_callback,
+ void *data, struct unit_addrs_vector *addrs)
+{
+ struct dwarf_buf info;
+ struct abbrevs abbrevs;
+
+ memset (&addrs->vec, 0, sizeof addrs->vec);
+ addrs->count = 0;
+
+ /* Read through the .debug_info section. FIXME: Should we use the
+ .debug_aranges section? gdb and addr2line don't use it, but I'm
+ not sure why. */
+
+ info.name = ".debug_info";
+ info.start = dwarf_info;
+ info.buf = dwarf_info;
+ info.left = dwarf_info_size;
+ info.is_bigendian = is_bigendian;
+ info.error_callback = error_callback;
+ info.data = data;
+ info.reported_underflow = 0;
+
+ memset (&abbrevs, 0, sizeof abbrevs);
+ while (info.left > 0)
+ {
+ const unsigned char *unit_data_start;
+ uint64_t len;
+ int is_dwarf64;
+ struct dwarf_buf unit_buf;
+ int version;
+ uint64_t abbrev_offset;
+ int addrsize;
+ struct unit *u;
+
+ if (info.reported_underflow)
+ goto fail;
+
+ unit_data_start = info.buf;
+
+ is_dwarf64 = 0;
+ len = read_uint32 (&info);
+ if (len == 0xffffffff)
+ {
+ len = read_uint64 (&info);
+ is_dwarf64 = 1;
+ }
+
+ unit_buf = info;
+ unit_buf.left = len;
+
+ if (!advance (&info, len))
+ goto fail;
+
+ version = read_uint16 (&unit_buf);
+ if (version < 2 || version > 4)
+ {
+ dwarf_buf_error (&unit_buf, "unrecognized DWARF version");
+ goto fail;
+ }
+
+ abbrev_offset = read_offset (&unit_buf, is_dwarf64);
+ if (!read_abbrevs (state, abbrev_offset, dwarf_abbrev, dwarf_abbrev_size,
+ is_bigendian, error_callback, data, &abbrevs))
+ goto fail;
+
+ addrsize = read_byte (&unit_buf);
+
+ u = ((struct unit *)
+ backtrace_alloc (state, sizeof *u, error_callback, data));
+ if (u == NULL)
+ goto fail;
+ u->unit_data = unit_buf.buf;
+ u->unit_data_len = unit_buf.left;
+ u->unit_data_offset = unit_buf.buf - unit_data_start;
+ u->version = version;
+ u->is_dwarf64 = is_dwarf64;
+ u->addrsize = addrsize;
+ u->filename = NULL;
+ u->comp_dir = NULL;
+ u->abs_filename = NULL;
+ u->lineoff = 0;
+ u->abbrevs = abbrevs;
+ memset (&abbrevs, 0, sizeof abbrevs);
+
+ /* The actual line number mappings will be read as needed. */
+ u->lines = NULL;
+ u->lines_count = 0;
+ u->function_addrs = NULL;
+ u->function_addrs_count = 0;
+
+ if (!find_address_ranges (state, base_address, &unit_buf,
+ dwarf_str, dwarf_str_size,
+ dwarf_ranges, dwarf_ranges_size,
+ is_bigendian, error_callback, data,
+ u, addrs))
+ {
+ free_abbrevs (state, &u->abbrevs, error_callback, data);
+ backtrace_free (state, u, sizeof *u, error_callback, data);
+ goto fail;
+ }
+
+ if (unit_buf.reported_underflow)
+ {
+ free_abbrevs (state, &u->abbrevs, error_callback, data);
+ backtrace_free (state, u, sizeof *u, error_callback, data);
+ goto fail;
}
}
if (info.reported_underflow)
+2013-11-25 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ * configure.ac (GCC_LIBSTDCXX_RAW_CXX_FLAGS): Remove.
+ * configure: Regenerate.
+
2013-11-22 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
* configure.ac (libcilkrts_cv_have_attribute_visibility): Check
INSTALL_DATA
INSTALL_SCRIPT
INSTALL_PROGRAM
-LIBSTDCXX_RAW_CXX_LDFLAGS
-LIBSTDCXX_RAW_CXX_CXXFLAGS
-target_noncanonical
target_os
target_vendor
target_cpu
target_alias=${target_alias-$host_alias}
- case ${build_alias} in
- "") build_noncanonical=${build} ;;
- *) build_noncanonical=${build_alias} ;;
-esac
-
- case ${host_alias} in
- "") host_noncanonical=${build_noncanonical} ;;
- *) host_noncanonical=${host_alias} ;;
-esac
-
- case ${target_alias} in
- "") target_noncanonical=${host_noncanonical} ;;
- *) target_noncanonical=${target_alias} ;;
-esac
-
-
-
-
-
- LIBSTDCXX_RAW_CXX_CXXFLAGS="\
- -I\$(top_builddir)/../libstdc++-v3/include \
- -I\$(top_builddir)/../libstdc++-v3/include/\$(target_noncanonical) \
- -I\$(top_srcdir)/../libstdc++-v3/libsupc++"
- LIBSTDCXX_RAW_CXX_LDFLAGS="\
- \$(top_builddir)/../libstdc++-v3/src/libstdc++.la"
-
-
-
am__api_version='1.11'
# Find a good install program. We prefer a C program (faster),
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11090 "configure"
+#line 11059 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11196 "configure"
+#line 11165 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
AC_CANONICAL_SYSTEM
target_alias=${target_alias-$host_alias}
AC_SUBST(target_alias)
-GCC_LIBSTDCXX_RAW_CXX_FLAGS
AM_INIT_AUTOMAKE(foreign no-dist)
AM_MAINTAINER_MODE
+2013-12-04 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * longlong.h: Delete (moved to include/).
+
+2013-12-03 Adhemerval Zanella <azanella@linux.vnet.ibm.com>
+
+ * config/rs6000/ibm-ldouble.c (__gcc_qadd): Fix add
+ of normal number and qNaN to not raise an inexact exception.
+
+2013-11-28 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/i386/32/sfp-machine.h (__FP_FRAC_ADDI_4): New macro.
+
+2013-11-28 Matthew Leach <matthew.leach@arm.com>
+
+ * config/aarch64/linux-unwind.h (aarch64_fallback_frame_state): Check
+ for correct opcodes on BE.
+
+2013-11-27 Uros Bizjak <ubizjak@gmail.com>
+
+ * soft-fp/op-4.h: Update from glibc.
+
+2013-11-27 Kugan Vivekanandarajah <kuganv@linaro.org>
+
+ * libgcc2.c (__udivmoddi4): Define new implementation when
+ TARGET_HAS_NO_HW_DIVIDE is defined, for processors without any
+ divide instructions.
+
+2013-11-25 Oleg Endo <olegendo@gcc.gnu.org>
+
+ * config/sh/crt1.S (start): Don't do VBR_SETUP for SH2E.
+
+2013-11-25 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ * config/t-softfp (soft-fp-objects-base): New variable.
+ (soft-fp-objects): Use it.
+
+2013-11-23 David Edelson <dje.gcc@gmail.com>
+ Andrew Dixie <andrewd@gentrack.com>
+
+ PR target/33704
+ * config/rs6000/aixinitfini.c: New file.
+ * config/rs6000/t-aix-cxa (LIB2ADD_ST): Add aixinitfini.c.
+ * config/rs6000/libgcc-aix-cxa.ver (GCC_4.9): Add libgcc initfini
+ symbols.
+
+2013-11-22 Yuri Rumyantsev <ysrumyan@gmail.com>
+
+ * config/i386/cpuinfo.c (get_intel_cpu): Add Silvermont cases.
+
2013-11-18 Jan Hubicka <jh@suse.cz>
* libgcov-driver.c (run_accounted): Make global level static.
#include <signal.h>
#include <sys/ucontext.h>
+
+/* Since insns are always stored LE, on a BE system the opcodes will
+ be loaded byte-reversed. Therefore, define two sets of opcodes,
+ one for LE and one for BE. */
+
+#if __AARCH64EB__
+#define MOVZ_X8_8B 0x681180d2
+#define SVC_0 0x010000d4
+#else
+#define MOVZ_X8_8B 0xd2801168
+#define SVC_0 0xd4000001
+#endif
+
#define MD_FALLBACK_FRAME_STATE_FOR aarch64_fallback_frame_state
static _Unwind_Reason_Code
0xd2801168 movz x8, #0x8b
0xd4000001 svc 0x0
*/
- if (pc[0] != 0xd2801168 || pc[1] != 0xd4000001)
+ if (pc[0] != MOVZ_X8_8B || pc[1] != SVC_0)
{
return _URC_END_OF_STACK;
}
"g" ((USItype) (y1)), \
"2" ((USItype) (x0)), \
"g" ((USItype) (y0)))
+#define __FP_FRAC_ADDI_4(x3,x2,x1,x0,i) \
+ __asm__ ("add{l} {%4,%3|%3,%4}\n\t" \
+ "adc{l} {$0,%2|%2,0}\n\t" \
+ "adc{l} {$0,%1|%1,0}\n\t" \
+ "adc{l} {$0,%0|%0,0}" \
+ : "+r" ((USItype) (x3)), \
+ "+&r" ((USItype) (x2)), \
+ "+&r" ((USItype) (x1)), \
+ "+&r" ((USItype) (x0)) \
+ : "g" ((USItype) (i)))
#define _FP_MUL_MEAT_S(R,X,Y) \
/* Atom. */
__cpu_model.__cpu_type = INTEL_ATOM;
break;
+ case 0x37:
+ case 0x4d:
+ /* Silvermont. */
+ __cpu_model.__cpu_type = INTEL_SLM;
+ break;
case 0x1a:
case 0x1e:
case 0x1f:
--- /dev/null
+/* FIXME: rename this file */
+
+/*
+ Artificially create _GLOBAL_AIX[ID]_shr_o symbols in libgcc.a.
+
+ This means that libstdc++.a can invoke these symbols and they are resolved
+ regardless of whether libstdc++.a is linked against libgcc_s.a or libgcc.a.
+
+ The symbols are created in libgcc_s.a by collect2 as there are exception
+ frames to register for LIB2_DIVMOD_FUNCS.
+
+ The symbols are NOT created by collect2 for libgcc.a, because libgcc.a is
+ a 'real' archive containing objects and collect2 is not invoked.
+
+ libstdc++.a is linked against libgcc.a when handling the command line
+ options '-static-libgcc -static-libstdc++'.
+*/
+
+void _GLOBAL__AIXI_shr_o (void);
+void _GLOBAL__AIXD_shr_o (void);
+
+void
+_GLOBAL__AIXI_shr_o (void)
+{
+ return;
+}
+
+void
+_GLOBAL__AIXD_shr_o (void)
+{
+ return;
+}
+
if (nonfinite (z))
{
+ if (fabs (z) != inf())
+ return z;
z = cc + aa + c + a;
if (nonfinite (z))
return z;
__cxa_atexit
__cxa_finalize
}
+
+GCC_4.9 {
+ _GLOBAL__AIXI_shr_o
+ _GLOBAL__AIXD_shr_o
+}
LIB2ADDEH += $(srcdir)/config/rs6000/cxa_atexit.c \
$(srcdir)/config/rs6000/cxa_finalize.c
+LIB2ADD_ST += $(srcdir)/config/rs6000/aixinitfini.c
+
SHLIB_MAPFILES += $(srcdir)/config/rs6000/libgcc-aix-cxa.ver
crtcxa.o: $(srcdir)/config/rs6000/crtcxa.c
start:
mov.l stack_k,r15
-#if defined (__SH3__) || (defined (__SH_FPU_ANY__) && ! defined (__SH2A__)) || defined (__SH4_NOFPU__)
+#if defined (__SH3__) || (defined (__SH_FPU_ANY__) && ! defined (__SH2E__) && ! defined (__SH2A__)) || defined (__SH4_NOFPU__)
#define VBR_SETUP
! before zeroing the bss ...
! if the vbr is already set to vbr_start then the program has been restarted
# for the functions in the soft-fp files have not been brought across
# from glibc.
-soft-fp-objects = $(addsuffix $(objext), $(softfp_file_list)) \
- $(addsuffix _s$(objext), $(softfp_file_list))
+soft-fp-objects-base = $(basename $(notdir $(softfp_file_list)))
+
+soft-fp-objects = $(addsuffix $(objext), $(soft-fp-objects-base)) \
+ $(addsuffix _s$(objext), $(soft-fp-objects-base))
$(soft-fp-objects) : INTERNAL_CFLAGS += -Wno-missing-prototypes -Wno-type-limits
#endif
#ifdef L_udivmoddi4
+#ifdef TARGET_HAS_NO_HW_DIVIDE
+
+#if (defined (L_udivdi3) || defined (L_divdi3) || \
+ defined (L_umoddi3) || defined (L_moddi3))
+static inline __attribute__ ((__always_inline__))
+#endif
+UDWtype
+__udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp)
+{
+ UDWtype q = 0, r = n, y = d;
+ UWtype lz1, lz2, i, k;
+
+ /* Implements align divisor shift dividend method. This algorithm
+ aligns the divisor under the dividend and then perform number of
+ test-subtract iterations which shift the dividend left. Number of
+ iterations is k + 1 where k is the number of bit positions the
+ divisor must be shifted left to align it under the dividend.
+ quotient bits can be saved in the rightmost positions of the dividend
+ as it shifts left on each test-subtract iteration. */
+
+ if (y <= r)
+ {
+ lz1 = __builtin_clzll (d);
+ lz2 = __builtin_clzll (n);
+
+ k = lz1 - lz2;
+ y = (y << k);
+
+ /* Dividend can exceed 2 ^ (width − 1) − 1 but still be less than the
+ aligned divisor. Normal iteration can drops the high order bit
+ of the dividend. Therefore, first test-subtract iteration is a
+ special case, saving its quotient bit in a separate location and
+ not shifting the dividend. */
+ if (r >= y)
+ {
+ r = r - y;
+ q = (1ULL << k);
+ }
+
+ if (k > 0)
+ {
+ y = y >> 1;
+
+ /* k additional iterations where k regular test subtract shift
+ dividend iterations are done. */
+ i = k;
+ do
+ {
+ if (r >= y)
+ r = ((r - y) << 1) + 1;
+ else
+ r = (r << 1);
+ i = i - 1;
+ } while (i != 0);
+
+ /* First quotient bit is combined with the quotient bits resulting
+ from the k regular iterations. */
+ q = q + r;
+ r = r >> k;
+ q = q - (r << k);
+ }
+ }
+
+ if (rp)
+ *rp = r;
+ return q;
+}
+#else
#if (defined (L_udivdi3) || defined (L_divdi3) || \
defined (L_umoddi3) || defined (L_moddi3))
return ww.ll;
}
#endif
+#endif
#ifdef L_divdi3
DWtype
else if (rsize <= 2*_FP_W_TYPE_SIZE) \
{ \
r = X##_f[1]; \
- r <<= _FP_W_TYPE_SIZE; \
+ r = (rsize <= _FP_W_TYPE_SIZE ? 0 : r << _FP_W_TYPE_SIZE); \
r += X##_f[0]; \
} \
else \
/* I'm feeling lazy so we deal with int == 3words (implausible)*/ \
/* and int == 4words as a single case. */ \
r = X##_f[3]; \
- r <<= _FP_W_TYPE_SIZE; \
+ r = (rsize <= _FP_W_TYPE_SIZE ? 0 : r << _FP_W_TYPE_SIZE); \
r += X##_f[2]; \
- r <<= _FP_W_TYPE_SIZE; \
+ r = (rsize <= _FP_W_TYPE_SIZE ? 0 : r << _FP_W_TYPE_SIZE); \
r += X##_f[1]; \
- r <<= _FP_W_TYPE_SIZE; \
+ r = (rsize <= _FP_W_TYPE_SIZE ? 0 : r << _FP_W_TYPE_SIZE); \
r += X##_f[0]; \
} \
} \
+2013-12-01 Uros Bizjak <ubizjak@gmail.com>
+
+ PR libfortran/59313
+ * intrinsics/erfc_scaled.c (erfc_scaled_r16): Also provide for
+ quadruple precision long double variant.
+
2013-11-20 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
* intrinsics/erfc_scaled.c (erfc_scaled_r16): Don't define if
#include "erfc_scaled_inc.c"
#endif
-#if defined(HAVE_GFC_REAL_16) && defined(GFC_REAL_16_IS_LONG_DOUBLE)
-#undef KIND
-#define KIND 16
-#include "erfc_scaled_inc.c"
-#endif
+#ifdef HAVE_GFC_REAL_16
+/* For quadruple-precision, netlib's implementation is
+ not accurate enough. We provide another one. */
#ifdef GFC_REAL_16_IS_FLOAT128
-/* For quadruple-precision (__float128), netlib's implementation is
- not accurate enough. We provide another one. */
+# define _THRESH -106.566990228185312813205074546585730Q
+# define _M_2_SQRTPI M_2_SQRTPIq
+# define _INF __builtin_infq()
+# define _ERFC(x) erfcq(x)
+# define _EXP(x) expq(x)
+
+#else
+
+# define _THRESH -106.566990228185312813205074546585730L
+# define _M_2_SQRTPI M_2_SQRTPIl
+# define _INF __builtin_infl()
+# ifdef HAVE_ERFCL
+# define _ERFC(x) erfcl(x)
+# endif
+# ifdef HAVE_EXPL
+# define _EXP(x) expl(x)
+# endif
+
+#endif
+
+#if defined(_ERFC) && defined(_EXP)
extern GFC_REAL_16 erfc_scaled_r16 (GFC_REAL_16);
export_proto(erfc_scaled_r16);
GFC_REAL_16
erfc_scaled_r16 (GFC_REAL_16 x)
{
- if (x < -106.566990228185312813205074546585730Q)
+ if (x < _THRESH)
{
- return __builtin_infq();
+ return _INF;
}
if (x < 12)
{
/* Compute directly as ERFC_SCALED(x) = ERFC(x) * EXP(X**2).
This is not perfect, but much better than netlib. */
- return erfcq(x) * expq(x * x);
+ return _ERFC(x) * _EXP(x * x);
}
else
{
n++;
}
- return (1 + sum) / x * (M_2_SQRTPIq / 2);
+ return (1 + sum) / x * (_M_2_SQRTPI / 2);
}
}
#endif
+#endif
# define EXP(x) exp(x)
# define TRUNC(x) trunc(x)
-#elif (KIND == 10) || (KIND == 16 && defined(GFC_REAL_16_IS_LONG_DOUBLE))
+#elif (KIND == 10)
# ifdef HAVE_EXPL
# define EXP(x) expl(x)
-7ebbddd21330
+65bf677ab8d8
The first line of this file holds the Mercurial revision number of the
last merge done from the master library sources.
runtime/go-unsafe-newarray.c \
runtime/go-unsafe-pointer.c \
runtime/go-unwind.c \
+ runtime/go-varargs.c \
runtime/chan.c \
runtime/cpuprof.c \
runtime/env_posix.c \
go-type-float.lo go-type-identity.lo go-type-interface.lo \
go-type-string.lo go-typedesc-equal.lo go-typestring.lo \
go-unsafe-new.lo go-unsafe-newarray.lo go-unsafe-pointer.lo \
- go-unwind.lo chan.lo cpuprof.lo env_posix.lo lfstack.lo \
- $(am__objects_1) mcache.lo mcentral.lo $(am__objects_2) \
- mfinal.lo mfixalloc.lo mgc0.lo mheap.lo msize.lo \
- $(am__objects_3) panic.lo parfor.lo print.lo proc.lo \
+ go-unwind.lo go-varargs.lo chan.lo cpuprof.lo env_posix.lo \
+ lfstack.lo $(am__objects_1) mcache.lo mcentral.lo \
+ $(am__objects_2) mfinal.lo mfixalloc.lo mgc0.lo mheap.lo \
+ msize.lo $(am__objects_3) panic.lo parfor.lo print.lo proc.lo \
runtime.lo signal_unix.lo thread.lo yield.lo $(am__objects_4) \
iface.lo malloc.lo map.lo mprof.lo netpoll.lo reflect.lo \
runtime1.lo sema.lo sigqueue.lo string.lo time.lo \
runtime/go-unsafe-newarray.c \
runtime/go-unsafe-pointer.c \
runtime/go-unwind.c \
+ runtime/go-varargs.c \
runtime/chan.c \
runtime/cpuprof.c \
runtime/env_posix.c \
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-unsafe-newarray.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-unsafe-pointer.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-unwind.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-varargs.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iface.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lfstack.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lock_futex.Plo@am__quote@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-unwind.lo `test -f 'runtime/go-unwind.c' || echo '$(srcdir)/'`runtime/go-unwind.c
+go-varargs.lo: runtime/go-varargs.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-varargs.lo -MD -MP -MF $(DEPDIR)/go-varargs.Tpo -c -o go-varargs.lo `test -f 'runtime/go-varargs.c' || echo '$(srcdir)/'`runtime/go-varargs.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/go-varargs.Tpo $(DEPDIR)/go-varargs.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/go-varargs.c' object='go-varargs.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-varargs.lo `test -f 'runtime/go-varargs.c' || echo '$(srcdir)/'`runtime/go-varargs.c
+
chan.lo: runtime/chan.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT chan.lo -MD -MP -MF $(DEPDIR)/chan.Tpo -c -o chan.lo `test -f 'runtime/chan.c' || echo '$(srcdir)/'`runtime/chan.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/chan.Tpo $(DEPDIR)/chan.Plo
/* Define to 1 if the system has the type `off64_t'. */
#undef HAVE_OFF64_T
+/* Define to 1 if you have the `open64' function. */
+#undef HAVE_OPEN64
+
/* Define to 1 if you have the `openat' function. */
#undef HAVE_OPENAT
x86_64-*linux*)
LD="${LD-ld} -m elf_i386"
;;
- powerpc64le-*)
+ powerpc64le-*linux*)
LD="${LD-ld} -m elf32lppclinux"
;;
- powerpc64-*)
+ powerpc64-*linux*)
LD="${LD-ld} -m elf32ppclinux"
;;
s390x-*linux*)
x86_64-*linux*)
LD="${LD-ld} -m elf_x86_64"
;;
- powerpcle-*)
+ powerpcle-*linux*)
LD="${LD-ld} -m elf64lppc"
;;
- powerpc-*)
+ powerpc-*linux*)
LD="${LD-ld} -m elf64ppc"
;;
s390*-*linux*|s390*-*tpf*)
x86_64-*linux*)
LD="${LD-ld} -m elf_i386"
;;
- powerpc64le-*)
+ powerpc64le-*linux*)
LD="${LD-ld} -m elf32lppclinux"
;;
- powerpc64-*)
+ powerpc64-*linux*)
LD="${LD-ld} -m elf32ppclinux"
;;
s390x-*linux*)
x86_64-*linux*)
LD="${LD-ld} -m elf_x86_64"
;;
- powerpcle-*)
+ powerpcle-*linux*)
LD="${LD-ld} -m elf64lppc"
;;
- powerpc-*)
+ powerpc-*linux*)
LD="${LD-ld} -m elf64ppc"
;;
s390*-*linux*|s390*-*tpf*)
fi
-for ac_func in accept4 dup3 epoll_create1 faccessat fallocate fchmodat fchownat futimesat getxattr inotify_add_watch inotify_init inotify_init1 inotify_rm_watch listxattr mkdirat mknodat openat pipe2 removexattr renameat setxattr sync_file_range splice tee unlinkat unshare utimensat
+for ac_func in accept4 dup3 epoll_create1 faccessat fallocate fchmodat fchownat futimesat getxattr inotify_add_watch inotify_init inotify_init1 inotify_rm_watch listxattr mkdirat mknodat open64 openat pipe2 removexattr renameat setxattr sync_file_range splice tee unlinkat unshare utimensat
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
AM_CONDITIONAL(HAVE_STRERROR_R, test "$ac_cv_func_strerror_r" = yes)
AM_CONDITIONAL(HAVE_WAIT4, test "$ac_cv_func_wait4" = yes)
-AC_CHECK_FUNCS(accept4 dup3 epoll_create1 faccessat fallocate fchmodat fchownat futimesat getxattr inotify_add_watch inotify_init inotify_init1 inotify_rm_watch listxattr mkdirat mknodat openat pipe2 removexattr renameat setxattr sync_file_range splice tee unlinkat unshare utimensat)
+AC_CHECK_FUNCS(accept4 dup3 epoll_create1 faccessat fallocate fchmodat fchownat futimesat getxattr inotify_add_watch inotify_init inotify_init1 inotify_rm_watch listxattr mkdirat mknodat open64 openat pipe2 removexattr renameat setxattr sync_file_range splice tee unlinkat unshare utimensat)
AC_TYPE_OFF_T
AC_CHECK_TYPES([loff_t])
}
// ColumnConverter may be optionally implemented by Stmt if the
-// the statement is aware of its own columns' types and can
-// convert from any type to a driver Value.
+// statement is aware of its own columns' types and can convert from
+// any type to a driver Value.
type ColumnConverter interface {
// ColumnConverter returns a ValueConverter for the provided
// column index. If the type of a specific column isn't known
connRequests *list.List // of connRequest
numOpen int
pendingOpens int
- // Used to sygnal the need for new connections
+ // Used to signal the need for new connections
// a goroutine running connectionOpener() reads on this chan and
// maybeOpenNewConnections sends on the chan (one send per needed connection)
// It is closed during db.Close(). The close tells the connectionOpener
// A Result summarizes an executed SQL command.
type Result interface {
+ // LastInsertId returns the integer generated by the database
+ // in response to a command. Typically this will be from an
+ // "auto increment" column when inserting a new row. Not all
+ // databases support this feature, and the syntax of such
+ // statements varies.
LastInsertId() (int64, error)
+
+ // RowsAffected returns the number of rows affected by an
+ // update, insert, or delete. Not every database or database
+ // driver may support this.
RowsAffected() (int64, error)
}
formRef8 format = 0x14
formRefUdata format = 0x15
formIndirect format = 0x16
- // following are defined in DWARF 4
formSecOffset format = 0x17
- formExprLoc format = 0x18
+ formExprloc format = 0x18
formFlagPresent format = 0x19
formRefSig8 format = 0x20
)
case formUdata:
val = int64(b.uint())
- // exprloc
- case formExprLoc:
- val = b.bytes(int(b.uint()))
-
// flag
case formFlag:
val = b.uint8() == 1
+ // New in DWARF 4.
case formFlagPresent:
// The attribute is implicitly indicated as present, and no value is
// encoded in the debugging information entry itself.
val = true
- // lineptr, loclistptr, macptr, rangelistptr
- case formSecOffset:
- is64, known := b.format.dwarf64()
- if !known {
- b.error("unknown size for DW_FORM_sec_offset")
- } else if is64 {
- val = Offset(b.uint64())
- } else {
- val = Offset(b.uint32())
- }
-
// reference to other entry
case formRefAddr:
vers := b.format.version()
val = Offset(b.uint64()) + ubase
case formRefUdata:
val = Offset(b.uint()) + ubase
- case formRefSig8:
- val = b.uint64()
// string
case formString:
b.err = b1.err
return nil
}
+
+ // lineptr, loclistptr, macptr, rangelistptr
+ // New in DWARF 4, but clang can generate them with -gdwarf-2.
+ // Section reference, replacing use of formData4 and formData8.
+ case formSecOffset:
+ is64, known := b.format.dwarf64()
+ if !known {
+ b.error("unknown size for DW_FORM_sec_offset")
+ } else if is64 {
+ val = int64(b.uint64())
+ } else {
+ val = int64(b.uint32())
+ }
+
+ // exprloc
+ // New in DWARF 4.
+ case formExprloc:
+ val = b.bytes(int(b.uint()))
+
+ // reference
+ // New in DWARF 4.
+ case formRefSig8:
+ // 64-bit type signature.
+ val = b.uint64()
}
e.Field[i].Val = val
}
at top the level will fail. A struct field of chan or func type is treated exactly
like an unexported field and is ignored.
-Gob can encode a value of any type implementing the GobEncoder,
-encoding.BinaryMarshaler, or encoding.TextMarshaler interfaces by calling the
-corresponding method, in that order of preference.
+Gob can encode a value of any type implementing the GobEncoder or
+encoding.BinaryMarshaler interfaces by calling the corresponding method,
+in that order of preference.
-Gob can decode a value of any type implementing the GobDecoder,
-encoding.BinaryUnmarshaler, or encoding.TextUnmarshaler interfaces by calling
-the corresponding method, again in that order of preference.
+Gob can decode a value of any type implementing the GobDecoder or
+encoding.BinaryUnmarshaler interfaces by calling the corresponding method,
+again in that order of preference.
Encoding Details
"errors"
"fmt"
"io"
+ "net"
"strings"
"testing"
"time"
t.Fatalf("expected nil, got %v", err2)
}
}
+
+func TestNetIP(t *testing.T) {
+ // Encoding of net.IP{1,2,3,4} in Go 1.1.
+ enc := []byte{0x07, 0x0a, 0x00, 0x04, 0x01, 0x02, 0x03, 0x04}
+
+ var ip net.IP
+ err := NewDecoder(bytes.NewReader(enc)).Decode(&ip)
+ if err != nil {
+ t.Fatalf("decode: %v", err)
+ }
+ if ip.String() != "1.2.3.4" {
+ t.Errorf("decoded to %v, want 1.2.3.4", ip.String())
+ }
+}
ut.externalEnc, ut.encIndir = xGob, indir
} else if ok, indir := implementsInterface(ut.user, binaryMarshalerInterfaceType); ok {
ut.externalEnc, ut.encIndir = xBinary, indir
- } else if ok, indir := implementsInterface(ut.user, textMarshalerInterfaceType); ok {
- ut.externalEnc, ut.encIndir = xText, indir
}
+ // NOTE(rsc): Would like to allow MarshalText here, but results in incompatibility
+ // with older encodings for net.IP. See golang.org/issue/6760.
+ // } else if ok, indir := implementsInterface(ut.user, textMarshalerInterfaceType); ok {
+ // ut.externalEnc, ut.encIndir = xText, indir
+ // }
+
if ok, indir := implementsInterface(ut.user, gobDecoderInterfaceType); ok {
ut.externalDec, ut.decIndir = xGob, indir
} else if ok, indir := implementsInterface(ut.user, binaryUnmarshalerInterfaceType); ok {
ut.externalDec, ut.decIndir = xBinary, indir
- } else if ok, indir := implementsInterface(ut.user, textUnmarshalerInterfaceType); ok {
- ut.externalDec, ut.decIndir = xText, indir
}
+ // See note above.
+ // } else if ok, indir := implementsInterface(ut.user, textUnmarshalerInterfaceType); ok {
+ // ut.externalDec, ut.decIndir = xText, indir
+ // }
+
userTypeCache[rt] = ut
return
}
// Unmarshal records the attribute value in that field.
//
// * If the XML element contains character data, that data is
-// accumulated in the first struct field that has tag "chardata".
+// accumulated in the first struct field that has tag ",chardata".
// The struct field may have type []byte or string.
// If there is no such field, the character data is discarded.
//
if q == ' ' && p == '.' && (!unicode.IsUpper(pp) || unicode.IsUpper(ppp)) {
return i
}
+ if p == '。' || p == '.' {
+ return i
+ }
ppp, pp, p = pp, p, q
}
return len(s)
{"P. Q. ", 8, "P. Q."},
{"Package Καλημέρα κόσμε.", 36, "Package Καλημέρα κόσμε."},
{"Package こんにちは 世界\n", 31, "Package こんにちは 世界"},
+ {"Package こんにちは。世界", 26, "Package こんにちは。"},
+ {"Package 안녕.世界", 17, "Package 안녕."},
{"Package foo does bar.", 21, "Package foo does bar."},
{"Copyright 2012 Google, Inc. Package foo does bar.", 27, ""},
{"All Rights reserved. Package foo does bar.", 20, ""},
hostsPath = p
}
+// https://code.google.com/p/go/issues/detail?id=6646
+func TestSingleLineHostsFile(t *testing.T) {
+ p := hostsPath
+ hostsPath = "testdata/hosts_singleline"
+
+ ips := lookupStaticHost("odin")
+ if len(ips) != 1 || ips[0] != "127.0.0.2" {
+ t.Errorf("lookupStaticHost = %v, want %v", ips, []string{"127.0.0.2"})
+ }
+
+ hostsPath = p
+}
+
func TestLookupHost(t *testing.T) {
// Can't depend on this to return anything in particular,
// but if it does return something, make sure it doesn't
func (c *dumpConn) SetReadDeadline(t time.Time) error { return nil }
func (c *dumpConn) SetWriteDeadline(t time.Time) error { return nil }
+type neverEnding byte
+
+func (b neverEnding) Read(p []byte) (n int, err error) {
+ for i := range p {
+ p[i] = byte(b)
+ }
+ return len(p), nil
+}
+
// DumpRequestOut is like DumpRequest but includes
// headers that the standard http.Transport adds,
// such as User-Agent.
func DumpRequestOut(req *http.Request, body bool) ([]byte, error) {
save := req.Body
+ dummyBody := false
if !body || req.Body == nil {
req.Body = nil
+ if req.ContentLength != 0 {
+ req.Body = ioutil.NopCloser(io.LimitReader(neverEnding('x'), req.ContentLength))
+ dummyBody = true
+ }
} else {
var err error
save, req.Body, err = drainBody(req.Body)
if err != nil {
return nil, err
}
- return buf.Bytes(), nil
+ dump := buf.Bytes()
+
+ // If we used a dummy body above, remove it now.
+ // TODO: if the req.ContentLength is large, we allocate memory
+ // unnecessarily just to slice it off here. But this is just
+ // a debug function, so this is acceptable for now. We could
+ // discard the body earlier if this matters.
+ if dummyBody {
+ if i := bytes.Index(dump, []byte("\r\n\r\n")); i >= 0 {
+ dump = dump[:i+4]
+ }
+ }
+ return dump, nil
}
// delegateReader is a reader that delegates to another reader,
WantDump string
WantDumpOut string
+ NoBody bool // if true, set DumpRequest{,Out} body to false
}
var dumpTests = []dumpTest{
"User-Agent: Go 1.1 package http\r\n" +
"Accept-Encoding: gzip\r\n\r\n",
},
+
+ // Request with Body, but Dump requested without it.
+ {
+ Req: http.Request{
+ Method: "POST",
+ URL: &url.URL{
+ Scheme: "http",
+ Host: "post.tld",
+ Path: "/",
+ },
+ ContentLength: 6,
+ ProtoMajor: 1,
+ ProtoMinor: 1,
+ },
+
+ Body: []byte("abcdef"),
+
+ WantDumpOut: "POST / HTTP/1.1\r\n" +
+ "Host: post.tld\r\n" +
+ "User-Agent: Go 1.1 package http\r\n" +
+ "Content-Length: 6\r\n" +
+ "Accept-Encoding: gzip\r\n\r\n",
+
+ NoBody: true,
+ },
}
func TestDumpRequest(t *testing.T) {
if tt.WantDump != "" {
setBody()
- dump, err := DumpRequest(&tt.Req, true)
+ dump, err := DumpRequest(&tt.Req, !tt.NoBody)
if err != nil {
t.Errorf("DumpRequest #%d: %s", i, err)
continue
if tt.WantDumpOut != "" {
setBody()
- dump, err := DumpRequestOut(&tt.Req, true)
+ dump, err := DumpRequestOut(&tt.Req, !tt.NoBody)
if err != nil {
t.Errorf("DumpRequestOut #%d: %s", i, err)
continue
if n >= 0 {
f.data = f.data[0 : ln+n]
}
- if err == io.EOF {
+ if err == io.EOF || err == io.ErrUnexpectedEOF {
f.atEOF = true
}
}
--- /dev/null
+127.0.0.2 odin
\ No newline at end of file
// and upper case after each dash.
// (Host, User-Agent, If-Modified-Since).
// MIME headers are ASCII only, so no Unicode issues.
- if a[i] == ' ' {
- a[i] = '-'
- upper = true
- continue
- }
c := a[i]
- if upper && 'a' <= c && c <= 'z' {
+ if c == ' ' {
+ c = '-'
+ } else if upper && 'a' <= c && c <= 'z' {
c -= toLower
} else if !upper && 'A' <= c && c <= 'Z' {
c += toLower
{"user-agent", "User-Agent"},
{"USER-AGENT", "User-Agent"},
{"üser-agenT", "üser-Agent"}, // non-ASCII unchanged
+
+ // This caused a panic due to mishandling of a space:
+ {"C Ontent-Transfer-Encoding", "C-Ontent-Transfer-Encoding"},
+ {"foo bar", "Foo-Bar"},
}
func TestCanonicalMIMEHeaderKey(t *testing.T) {
return err
}
-// Encode encodes the values into ``URL encoded'' form.
-// e.g. "foo=bar&bar=baz"
+// Encode encodes the values into ``URL encoded'' form
+// ("bar=baz&foo=quux") sorted by key.
func (v Values) Encode() string {
if v == nil {
return ""
fi = make([]FileInfo, len(names))
for i, filename := range names {
fip, lerr := lstat(dirname + filename)
- if lerr == nil {
- fi[i] = fip
- } else {
+ if lerr != nil {
fi[i] = &fileStat{name: filename}
- if err == nil {
- err = lerr
- }
+ continue
}
+ fi[i] = fip
}
return fi, err
}
defer func() { *LstatP = Lstat }()
dirs, err := handle.Readdir(-1)
- if err != ErrInvalid {
- t.Fatalf("Expected Readdir to return ErrInvalid, got %v", err)
+ if err != nil {
+ t.Fatalf("Expected Readdir to return no error, got %v", err)
}
foundfail := false
for _, dir := range dirs {
esp uint32 // 0x0
eax uint32 // 0x4
st0 uint64 // 0x8
+ sr int32 // 0x10
}
- */
+ The sr field is set by the function to a non-zero value if
+ the function takes a struct hidden pointer that must be
+ popped off the stack. */
pushl %ebp
.LCFI0:
movsd -16(%ebp), %xmm0
#endif
+ movl -8(%ebp), %edx
+
addl $36, %esp
popl %ebx
.LCFI3:
popl %ebp
.LCFI4:
+
+ testl %edx,%edx
+ jne 1f
ret
+1:
+ ret $4
.LFE1:
#ifdef __ELF__
.size reflect.makeFuncStub, . - reflect.makeFuncStub
esp uint32
eax uint32 // Value to return in %eax.
st0 uint64 // Value to return in %st(0).
+ sr int32 // Set to non-zero if hidden struct pointer.
}
// MakeFuncStubGo implements the 386 calling convention for MakeFunc.
in := make([]Value, 0, len(ftyp.in))
ap := uintptr(regs.esp)
+ regs.sr = 0
var retPtr unsafe.Pointer
if retStruct {
retPtr = *(*unsafe.Pointer)(unsafe.Pointer(ap))
ap += ptrSize
+ regs.sr = 1
}
for _, rt := range ftyp.in {
"bytes"
"fmt"
"hash/crc32"
+ "math/big"
"os/exec"
"regexp"
"runtime"
}
})
+ if len(need) == 0 {
+ return
+ }
+
var total uintptr
for i, name := range need {
total += have[i]
}
}
+// Test that profiling of division operations is okay, especially on ARM. See issue 6681.
+func TestMathBigDivide(t *testing.T) {
+ testCPUProfile(t, nil, func() {
+ t := time.After(5 * time.Second)
+ pi := new(big.Int)
+ for {
+ for i := 0; i < 100; i++ {
+ n := big.NewInt(2646693125139304345)
+ d := big.NewInt(842468587426513207)
+ pi.Div(n, d)
+ }
+ select {
+ case <-t:
+ return
+ default:
+ }
+ }
+ })
+}
+
// Operating systems that are expected to fail the tests. See issue 6047.
var badOS = map[string]bool{
"darwin": true,
func (r *singleStringReplacer) Replace(s string) string {
var buf []byte
- i := 0
+ i, matched := 0, false
for {
match := r.finder.next(s[i:])
if match == -1 {
break
}
+ matched = true
buf = append(buf, s[i:i+match]...)
buf = append(buf, r.value...)
i += match + len(r.finder.pattern)
}
- if buf == nil {
+ if !matched {
return s
}
buf = append(buf, s[i:]...)
testCases = append(testCases,
testCase{abcMatcher, "", ""},
testCase{abcMatcher, "ab", "ab"},
+ testCase{abcMatcher, "abc", "[match]"},
testCase{abcMatcher, "abcd", "[match]d"},
testCase{abcMatcher, "cabcabcdabca", "c[match][match]d[match]a"},
)
+ // Issue 6659 cases (more single string replacer)
+
+ noHello := NewReplacer("Hello", "")
+ testCases = append(testCases,
+ testCase{noHello, "Hello", ""},
+ testCase{noHello, "Hellox", "x"},
+ testCase{noHello, "xHello", "x"},
+ testCase{noHello, "xHellox", "xx"},
+ )
+
// No-arg test cases.
nop := NewReplacer()
//chdir(path *byte) _C_int
//sysnb raw_fcntl(fd int, cmd int, arg int) (val int, err Errno)
-//fcntl(fd _C_int, cmd _C_int, arg _C_int) _C_int
+//__go_fcntl(fd _C_int, cmd _C_int, arg _C_int) _C_int
//sysnb raw_close(fd int) (err Errno)
//close(fd _C_int) _C_int
import "unsafe"
//sys Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error)
-//openat(dirfd _C_int, path *byte, flags _C_int, mode Mode_t) _C_int
+//__go_openat(dirfd _C_int, path *byte, flags _C_int, mode Mode_t) _C_int
//sys futimesat(dirfd int, path *byte, times *[2]Timeval) (err error)
//futimesat(dirfd _C_int, path *byte, times *[2]Timeval) _C_int
//fchown(fd _C_int, uid Uid_t, gid Gid_t) _C_int
//sys fcntl(fd int, cmd int, arg int) (val int, err error)
-//fcntl(fd _C_int, cmd _C_int, arg _C_int) _C_int
+//__go_fcntl(fd _C_int, cmd _C_int, arg _C_int) _C_int
//sys Fdatasync(fd int) (err error)
//fdatasync(fd _C_int) _C_int
//mmap64(addr *byte, length Size_t, prot _C_int, flags _C_int, fd _C_int, offset Offset_t) *byte
//sys Open(path string, mode int, perm uint32) (fd int, err error)
-//open64(path *byte, mode _C_int, perm Mode_t) _C_int
+//__go_open64(path *byte, mode _C_int, perm Mode_t) _C_int
//sys Pread(fd int, p []byte, offset int64) (n int, err error)
//pread64(fd _C_int, buf *byte, count Size_t, offset Offset_t) Ssize_t
//mmap(addr *byte, length Size_t, prot _C_int, flags _C_int, fd _C_int, offset Offset_t) *byte
//sys Open(path string, mode int, perm uint32) (fd int, err error)
-//open(path *byte, mode _C_int, perm Mode_t) _C_int
+//__go_open(path *byte, mode _C_int, perm Mode_t) _C_int
//sys Pread(fd int, p []byte, offset int64) (n int, err error)
//pread(fd _C_int, buf *byte, count Size_t, offset Offset_t) Ssize_t
Pad [96]int8
}
-const SizeofSockaddrAny = 0x1c
+const SizeofSockaddrAny = 0x6c
type SockaddrInet4 struct {
Port int
//
// Example functions without output comments are compiled but not executed.
//
-// The naming convention to declare examples for a function F, a type T and
+// The naming convention to declare examples for the package, a function F, a type T and
// method M on type T are:
//
+// func Example() { ... }
// func ExampleF() { ... }
// func ExampleT() { ... }
// func ExampleT_M() { ... }
//
-// Multiple example functions for a type/function/method may be provided by
+// Multiple example functions for a package/type/function/method may be provided by
// appending a distinct suffix to the name. The suffix must start with a
// lower-case letter.
//
+// func Example_suffix() { ... }
// func ExampleF_suffix() { ... }
// func ExampleT_suffix() { ... }
// func ExampleT_M_suffix() { ... }
localOnce.Do(initTestingZone)
}
-var ParseTimeZone = parseTimeZone
+var (
+ ForceZipFileForTesting = forceZipFileForTesting
+ ParseTimeZone = parseTimeZone
+)
}
}
+func TestLoadLocationZipFile(t *testing.T) {
+ t.Skip("gccgo does not use the zip file")
+
+ ForceZipFileForTesting(true)
+ defer ForceZipFileForTesting(false)
+
+ _, err := LoadLocation("Australia/Sydney")
+ if err != nil {
+ t.Fatal(err)
+ }
+}
+
var rubyTests = []ParseTest{
{"RubyDate", RubyDate, "Thu Feb 04 21:00:57 -0800 2010", true, true, 1, 0},
// Ignore the time zone in the test. If it parses, it'll be OK.
}
return nil, errors.New("unknown time zone " + name)
}
+
+func forceZipFileForTesting(zipOnly bool) {
+ // We only use the zip file anyway.
+}
"/usr/share/zoneinfo/",
"/usr/share/lib/zoneinfo/",
"/usr/lib/locale/TZ/",
- runtime.GOROOT() + "/lib/time/zoneinfo/",
+ runtime.GOROOT() + "/lib/time/zoneinfo.zip",
+}
+
+var origZoneDirs = zoneDirs
+
+func forceZipFileForTesting(zipOnly bool) {
+ zoneDirs = make([]string, len(origZoneDirs))
+ copy(zoneDirs, origZoneDirs)
+ if zipOnly {
+ for i := 0; i < len(zoneDirs)-1; i++ {
+ zoneDirs[i] = "/XXXNOEXIST"
+ }
+ }
}
func initLocal() {
}
return nil, errors.New("unknown time zone " + name)
}
+
+func forceZipFileForTesting(zipOnly bool) {
+ // We only use the zip file anyway.
+}
#include "runtime.h"
#include "array.h"
+/* This is set to non-zero when calling backtrace_full. This is used
+ to avoid getting hanging on a recursive lock in dl_iterate_phdr on
+ older versions of glibc when a SIGPROF signal arrives while
+ collecting a backtrace. */
+
+uint32 runtime_in_callers;
+
/* Argument passed to callback function. */
struct callers_data
data.skip = skip + 1;
data.index = 0;
data.max = m;
+ runtime_xadd (&runtime_in_callers, 1);
backtrace_full (__go_get_backtrace_state (), 0, callback, error_callback,
&data);
+ runtime_xadd (&runtime_in_callers, -1);
return data.index;
}
if (v < 0 || v > 0x10ffff)
v = 0xfffd;
+ else if (0xd800 <= v && v <= 0xdfff)
+ v = 0xfffd;
if (v <= 0x7f)
slen += 1;
character. */
if (v < 0 || v > 0x10ffff)
v = 0xfffd;
+ else if (0xd800 <= v && v <= 0xdfff)
+ v = 0xfffd;
if (v <= 0x7f)
*s++ = v;
G *g;
g = runtime_g ();
- runtime_traceback (g);
+ runtime_traceback ();
runtime_tracebackothers (g);
/* The gc library calls runtime_dumpregs here, and provides
/* The signal handler blocked signals; unblock them. */
i = sigfillset (&clear);
__go_assert (i == 0);
- i = sigprocmask (SIG_UNBLOCK, &clear, NULL);
+ i = pthread_sigmask (SIG_UNBLOCK, &clear, NULL);
__go_assert (i == 0);
}
--- /dev/null
+/* go-varargs.c -- functions for calling C varargs functions.
+
+ Copyright 2013 The Go Authors. All rights reserved.
+ Use of this source code is governed by a BSD-style
+ license that can be found in the LICENSE file. */
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <fcntl.h>
+
+/* The syscall package calls C functions. The Go compiler can not
+ represent a C varargs functions. On some systems it's important
+ that the declaration of a function match the call. This function
+ holds non-varargs C functions that the Go code can call. */
+
+int
+__go_open (char *path, int mode, mode_t perm)
+{
+ return open (path, mode, perm);
+}
+
+int
+__go_fcntl (int fd, int cmd, int arg)
+{
+ return fcntl (fd, cmd, arg);
+}
+
+#ifdef HAVE_OPEN64
+
+int
+__go_open64 (char *path, int mode, mode_t perm)
+{
+ return open64 (path, mode, perm);
+}
+
+#endif
+
+#ifdef HAVE_OPENAT
+
+int
+__go_openat (int fd, char *path, int flags, mode_t mode)
+{
+ return openat (fd, path, flags, mode);
+}
+
+#endif
#endif
sigemptyset(&old);
- sigprocmask(SIG_BLOCK, &clear, &old);
+ pthread_sigmask(SIG_BLOCK, &clear, &old);
ret = pthread_create(&tid, &attr, runtime_mstart, mp);
- sigprocmask(SIG_SETMASK, &old, nil);
+ pthread_sigmask(SIG_SETMASK, &old, nil);
if (ret != 0)
runtime_throw("pthread_create");
return;
}
n = 0;
+
+ if(runtime_atomicload(&runtime_in_callers) > 0) {
+ // If SIGPROF arrived while already fetching runtime
+ // callers we can have trouble on older systems
+ // because the unwind library calls dl_iterate_phdr
+ // which was not recursive in the past.
+ traceback = false;
+ }
+
if(traceback) {
n = runtime_callers(0, prof.locbuf, nelem(prof.locbuf));
for(i = 0; i < n; i++)
runtime_signalstack(m->gsignalstack, m->gsignalstacksize);
if (sigemptyset(&sigs) != 0)
runtime_throw("sigemptyset");
- sigprocmask(SIG_SETMASK, &sigs, nil);
+ pthread_sigmask(SIG_SETMASK, &sigs, nil);
}
// Called from dropm to undo the effect of an minit.
};
void runtime_hashinit(void);
-void runtime_traceback();
+void runtime_traceback(void);
void runtime_tracebackothers(G*);
/*
extern _Bool __go_file_line(uintptr, String*, String*, intgo *);
extern byte* runtime_progname();
extern void runtime_main(void*);
+extern uint32 runtime_in_callers;
int32 getproccount(void);
+2013-11-22 Cary Coutant <ccoutant@google.com>
+
+ PR other/59195
+ * cp-demangle.c (struct d_info_checkpoint): New struct.
+ (struct d_print_info): Add current_template field.
+ (d_operator_name): Set flag when processing a conversion
+ operator.
+ (cplus_demangle_type): When processing <template-args> for
+ a conversion operator, backtrack if necessary.
+ (d_expression_1): Renamed from d_expression.
+ (d_expression): New wrapper around d_expression_1.
+ (d_checkpoint): New function.
+ (d_backtrack): New function.
+ (d_print_init): Initialize current_template.
+ (d_print_comp): Set current_template.
+ (d_print_cast): Put current_template in scope for
+ printing conversion operator name.
+ (cplus_demangle_init_info): Initialize is_expression and
+ is_conversion.
+ * cp-demangle.h (struct d_info): Add is_expression and
+ is_conversion fields.
+ * testsuite/demangle-expected: New test cases.
+
2013-11-15 Andreas Schwab <schwab@linux-m68k.org>
* configure: Regenerate.
struct d_print_template *templates;
};
+/* Checkpoint structure to allow backtracking. This holds copies
+ of the fields of struct d_info that need to be restored
+ if a trial parse needs to be backtracked over. */
+
+struct d_info_checkpoint
+{
+ const char *n;
+ int next_comp;
+ int next_sub;
+ int did_subs;
+ int expansion;
+};
+
enum { D_PRINT_BUFFER_LENGTH = 256 };
struct d_print_info
{
struct d_saved_scope *saved_scopes;
/* Number of saved scopes in the above array. */
int num_saved_scopes;
+ /* The nearest enclosing template, if any. */
+ const struct demangle_component *current_template;
};
#ifdef CP_DEMANGLE_DEBUG
static struct demangle_component *d_substitution (struct d_info *, int);
+static void d_checkpoint (struct d_info *, struct d_info_checkpoint *);
+
+static void d_backtrack (struct d_info *, struct d_info_checkpoint *);
+
static void d_growable_string_init (struct d_growable_string *, size_t);
static inline void
if (c1 == 'v' && IS_DIGIT (c2))
return d_make_extended_operator (di, c2 - '0', d_source_name (di));
else if (c1 == 'c' && c2 == 'v')
- return d_make_comp (di, DEMANGLE_COMPONENT_CAST,
- cplus_demangle_type (di), NULL);
+ {
+ struct demangle_component *type;
+ int was_conversion = di->is_conversion;
+
+ di->is_conversion = ! di->is_expression;
+ type = cplus_demangle_type (di);
+ di->is_conversion = was_conversion;
+ return d_make_comp (di, DEMANGLE_COMPONENT_CAST, type, NULL);
+ }
else
{
/* LOW is the inclusive lower bound. */
ret = d_template_param (di);
if (d_peek_char (di) == 'I')
{
- /* This is <template-template-param> <template-args>. The
- <template-template-param> part is a substitution
+ /* This may be <template-template-param> <template-args>.
+ If this is the type for a conversion operator, we can
+ have a <template-template-param> here only by following
+ a derivation like this:
+
+ <nested-name>
+ -> <template-prefix> <template-args>
+ -> <prefix> <template-unqualified-name> <template-args>
+ -> <unqualified-name> <template-unqualified-name> <template-args>
+ -> <source-name> <template-unqualified-name> <template-args>
+ -> <source-name> <operator-name> <template-args>
+ -> <source-name> cv <type> <template-args>
+ -> <source-name> cv <template-template-param> <template-args> <template-args>
+
+ where the <template-args> is followed by another.
+ Otherwise, we must have a derivation like this:
+
+ <nested-name>
+ -> <template-prefix> <template-args>
+ -> <prefix> <template-unqualified-name> <template-args>
+ -> <unqualified-name> <template-unqualified-name> <template-args>
+ -> <source-name> <template-unqualified-name> <template-args>
+ -> <source-name> <operator-name> <template-args>
+ -> <source-name> cv <type> <template-args>
+ -> <source-name> cv <template-param> <template-args>
+
+ where we need to leave the <template-args> to be processed
+ by d_prefix (following the <template-prefix>).
+
+ The <template-template-param> part is a substitution
candidate. */
- if (! d_add_substitution (di, ret))
- return NULL;
- ret = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, ret,
- d_template_args (di));
+ if (! di->is_conversion)
+ {
+ if (! d_add_substitution (di, ret))
+ return NULL;
+ ret = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, ret,
+ d_template_args (di));
+ }
+ else
+ {
+ struct demangle_component *args;
+ struct d_info_checkpoint checkpoint;
+
+ d_checkpoint (di, &checkpoint);
+ args = d_template_args (di);
+ if (d_peek_char (di) == 'I')
+ {
+ if (! d_add_substitution (di, ret))
+ return NULL;
+ ret = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, ret,
+ args);
+ }
+ else
+ d_backtrack (di, &checkpoint);
+ }
}
break;
::= <expr-primary>
*/
-static struct demangle_component *
-d_expression (struct d_info *di)
+static inline struct demangle_component *
+d_expression_1 (struct d_info *di)
{
char peek;
{
d_advance (di, 2);
return d_make_comp (di, DEMANGLE_COMPONENT_PACK_EXPANSION,
- d_expression (di), NULL);
+ d_expression_1 (di), NULL);
}
else if (peek == 'f' && d_peek_next_char (di) == 'p')
{
&& d_check_char (di, '_'))
operand = d_exprlist (di, 'E');
else
- operand = d_expression (di);
+ operand = d_expression_1 (di);
if (suffix)
/* Indicate the suffix variant for d_print_comp. */
if (op_is_new_cast (op))
left = cplus_demangle_type (di);
else
- left = d_expression (di);
+ left = d_expression_1 (di);
if (!strcmp (code, "cl"))
right = d_exprlist (di, 'E');
else if (!strcmp (code, "dt") || !strcmp (code, "pt"))
right, d_template_args (di));
}
else
- right = d_expression (di);
+ right = d_expression_1 (di);
return d_make_comp (di, DEMANGLE_COMPONENT_BINARY, op,
d_make_comp (di,
if (!strcmp (code, "qu"))
{
/* ?: expression. */
- first = d_expression (di);
- second = d_expression (di);
- third = d_expression (di);
+ first = d_expression_1 (di);
+ second = d_expression_1 (di);
+ third = d_expression_1 (di);
}
else if (code[0] == 'n')
{
else if (d_peek_char (di) == 'i'
&& d_peek_next_char (di) == 'l')
/* initializer-list. */
- third = d_expression (di);
+ third = d_expression_1 (di);
else
return NULL;
}
}
}
+static struct demangle_component *
+d_expression (struct d_info *di)
+{
+ struct demangle_component *ret;
+ int was_expression = di->is_expression;
+
+ di->is_expression = 1;
+ ret = d_expression_1 (di);
+ di->is_expression = was_expression;
+ return ret;
+}
+
/* <expr-primary> ::= L <type> <(value) number> E
::= L <type> <(value) float> E
::= L <mangled-name> E
}
}
+static void
+d_checkpoint (struct d_info *di, struct d_info_checkpoint *checkpoint)
+{
+ checkpoint->n = di->n;
+ checkpoint->next_comp = di->next_comp;
+ checkpoint->next_sub = di->next_sub;
+ checkpoint->did_subs = di->did_subs;
+ checkpoint->expansion = di->expansion;
+}
+
+static void
+d_backtrack (struct d_info *di, struct d_info_checkpoint *checkpoint)
+{
+ di->n = checkpoint->n;
+ di->next_comp = checkpoint->next_comp;
+ di->next_sub = checkpoint->next_sub;
+ di->did_subs = checkpoint->did_subs;
+ di->expansion = checkpoint->expansion;
+}
+
/* Initialize a growable string. */
static void
dpi->saved_scopes = NULL;
dpi->num_saved_scopes = 0;
+ dpi->current_template = NULL;
}
/* Free a print information structure. */
{
struct d_print_mod *hold_dpm;
struct demangle_component *dcl;
+ const struct demangle_component *hold_current;
+
+ /* This template may need to be referenced by a cast operator
+ contained in its subtree. */
+ hold_current = dpi->current_template;
+ dpi->current_template = dc;
/* Don't push modifiers into a template definition. Doing so
could give the wrong definition for a template argument.
}
dpi->modifiers = hold_dpm;
+ dpi->current_template = hold_current;
return;
}
d_print_cast (struct d_print_info *dpi, int options,
const struct demangle_component *dc)
{
- if (d_left (dc)->type != DEMANGLE_COMPONENT_TEMPLATE)
- d_print_comp (dpi, options, d_left (dc));
- else
- {
- struct d_print_mod *hold_dpm;
- struct d_print_template dpt;
-
- /* It appears that for a templated cast operator, we need to put
- the template parameters in scope for the operator name, but
- not for the parameters. The effect is that we need to handle
- the template printing here. */
-
- hold_dpm = dpi->modifiers;
- dpi->modifiers = NULL;
+ struct d_print_template dpt;
+ /* For a cast operator, we need the template parameters from
+ the enclosing template in scope for processing the type. */
+ if (dpi->current_template != NULL)
+ {
dpt.next = dpi->templates;
dpi->templates = &dpt;
- dpt.template_decl = d_left (dc);
+ dpt.template_decl = dpi->current_template;
+ }
+ if (d_left (dc)->type != DEMANGLE_COMPONENT_TEMPLATE)
+ {
+ d_print_comp (dpi, options, d_left (dc));
+ if (dpi->current_template != NULL)
+ dpi->templates = dpt.next;
+ }
+ else
+ {
d_print_comp (dpi, options, d_left (d_left (dc)));
- dpi->templates = dpt.next;
+ /* For a templated cast operator, we need to remove the template
+ parameters from scope after printing the operator name,
+ so we need to handle the template printing here. */
+ if (dpi->current_template != NULL)
+ dpi->templates = dpt.next;
if (d_last_char (dpi) == '<')
d_append_char (dpi, ' ');
if (d_last_char (dpi) == '>')
d_append_char (dpi, ' ');
d_append_char (dpi, '>');
-
- dpi->modifiers = hold_dpm;
}
}
di->last_name = NULL;
di->expansion = 0;
+ di->is_expression = 0;
+ di->is_conversion = 0;
}
/* Internal implementation for the demangler. If MANGLED is a g++ v3 ABI
mangled name to the demangled name, such as standard
substitutions and builtin types. */
int expansion;
+ /* Non-zero if we are parsing an expression. */
+ int is_expression;
+ /* Non-zero if we are parsing the type operand of a conversion
+ operator, but not when in an expression. */
+ int is_conversion;
};
/* To avoid running past the ending '\0', don't:
--format=gnu-v3
_ZSt7forwardIRN1x14refobjiteratorINS0_3refINS0_4mime30multipart_section_processorObjIZ15get_body_parserIZZN14mime_processor21make_section_iteratorERKNS2_INS3_10sectionObjENS0_10ptrrefBaseEEEbENKUlvE_clEvEUlSB_bE_ZZNS6_21make_section_iteratorESB_bENKSC_clEvEUlSB_E0_ENS1_INS2_INS0_20outputrefiteratorObjIiEES8_EEEERKSsSB_OT_OT0_EUlmE_NS3_32make_multipart_default_discarderISP_EEEES8_EEEEEOT_RNSt16remove_referenceISW_E4typeE
x::refobjiterator<x::ref<x::mime::multipart_section_processorObj<x::refobjiterator<x::ref<x::outputrefiteratorObj<int>, x::ptrrefBase> > get_body_parser<mime_processor::make_section_iterator(x::ref<x::mime::sectionObj, x::ptrrefBase> const&, bool)::{lambda()#1}::operator()() const::{lambda(x::ref<x::mime::sectionObj, x::ptrrefBase> const&, bool)#1}, mime_processor::make_section_iterator(x::ref<x::mime::sectionObj, x::ptrrefBase> const&, bool)::{lambda()#1}::operator()() const::{lambda(x::ref<x::mime::sectionObj, x::ptrrefBase> const&)#2}>(std::string const&, x::ref<x::mime::sectionObj, x::ptrrefBase> const&, mime_processor::make_section_iterator(x::ref<x::mime::sectionObj, x::ptrrefBase> const&, bool)::{lambda()#1}::operator()() const::{lambda(x::ref<x::mime::sectionObj, x::ptrrefBase> const&, bool)#1}&&, mime_processor::make_section_iterator(x::ref<x::mime::sectionObj, x::ptrrefBase> const&, bool)::{lambda()#1}::operator()() const::{lambda(x::ref<x::mime::sectionObj, x::ptrrefBase> const&)#2}&&)::{lambda(unsigned long)#1}, x::mime::make_multipart_default_discarder<mime_processor::make_section_iterator(x::ref<x::mime::sectionObj, x::ptrrefBase> const&, bool)::{lambda()#1}::operator()() const::{lambda(x::ref<x::mime::sectionObj, x::ptrrefBase> const&, bool)#1}&&> >, x::ptrrefBase> >& std::forward<x::refobjiterator<x::ref<x::mime::multipart_section_processorObj<x::refobjiterator<x::ref<x::outputrefiteratorObj<int>, x::ptrrefBase> > get_body_parser<mime_processor::make_section_iterator(x::ref<x::mime::sectionObj, x::ptrrefBase> const&, bool)::{lambda()#1}::operator()() const::{lambda(x::ref<x::mime::sectionObj, x::ptrrefBase> const&, bool)#1}, mime_processor::make_section_iterator(x::ref<x::mime::sectionObj, x::ptrrefBase> const&, bool)::{lambda()#1}::operator()() const::{lambda(x::ref<x::mime::sectionObj, x::ptrrefBase> const&)#2}>(std::string const&, x::ref<x::mime::sectionObj, x::ptrrefBase> const&, mime_processor::make_section_iterator(x::ref<x::mime::sectionObj, x::ptrrefBase> const&, bool)::{lambda()#1}::operator()() const::{lambda(x::ref<x::mime::sectionObj, x::ptrrefBase> const&, bool)#1}&&, mime_processor::make_section_iterator(x::ref<x::mime::sectionObj, x::ptrrefBase> const&, bool)::{lambda()#1}::operator()() const::{lambda(x::ref<x::mime::sectionObj, x::ptrrefBase> const&)#2}&&)::{lambda(unsigned long)#1}, x::mime::make_multipart_default_discarder<mime_processor::make_section_iterator(x::ref<x::mime::sectionObj, x::ptrrefBase> const&, bool)::{lambda()#1}::operator()() const::{lambda(x::ref<x::mime::sectionObj, x::ptrrefBase> const&, bool)#1}&&> >, x::ptrrefBase> >&>(std::remove_reference<x::mime::multipart_section_processorObj<x::refobjiterator<x::ref<x::outputrefiteratorObj<int>, x::ptrrefBase> > get_body_parser<mime_processor::make_section_iterator(x::ref<x::mime::sectionObj, x::ptrrefBase> const&, bool)::{lambda()#1}::operator()() const::{lambda(x::ref<x::mime::sectionObj, x::ptrrefBase> const&, bool)#1}, mime_processor::make_section_iterator(x::ref<x::mime::sectionObj, x::ptrrefBase> const&, bool)::{lambda()#1}::operator()() const::{lambda(x::ref<x::mime::sectionObj, x::ptrrefBase> const&)#2}>(std::string const&, x::ref<x::mime::sectionObj, x::ptrrefBase> const&, mime_processor::make_section_iterator(x::ref<x::mime::sectionObj, x::ptrrefBase> const&, bool)::{lambda()#1}::operator()() const::{lambda(x::ref<x::mime::sectionObj, x::ptrrefBase> const&, bool)#1}&&, mime_processor::make_section_iterator(x::ref<x::mime::sectionObj, x::ptrrefBase> const&, bool)::{lambda()#1}::operator()() const::{lambda(x::ref<x::mime::sectionObj, x::ptrrefBase> const&)#2}&&)::{lambda(unsigned long)#1}, x::mime::make_multipart_default_discarder<mime_processor::make_section_iterator(x::ref<x::mime::sectionObj, x::ptrrefBase> const&, bool)::{lambda()#1}::operator()() const::{lambda(x::ref<x::mime::sectionObj, x::ptrrefBase> const&, bool)#1}&&> > >::type&)
+#
+--format=gnu-v3 --no-params
+_ZNK7strings8internal8SplitterINS_9delimiter5AnyOfENS_9SkipEmptyEEcvT_ISt6vectorI12basic_stringIcSt11char_traitsIcESaIcEESaISD_EEvEEv
+strings::internal::Splitter<strings::delimiter::AnyOf, strings::SkipEmpty>::operator std::vector<basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<basic_string<char, std::char_traits<char>, std::allocator<char> > > ><std::vector<basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<basic_string<char, std::char_traits<char>, std::allocator<char> > > >, void>() const
+strings::internal::Splitter<strings::delimiter::AnyOf, strings::SkipEmpty>::operator std::vector<basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<basic_string<char, std::char_traits<char>, std::allocator<char> > > ><std::vector<basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<basic_string<char, std::char_traits<char>, std::allocator<char> > > >, void>
+#
+--format=gnu-v3 --no-params
+_ZN1AcvT_I1CEEv
+A::operator C<C>()
+A::operator C<C>
+#
+--format=gnu-v3 --no-params
+_ZN1AcvPT_I1CEEv
+A::operator C*<C>()
+A::operator C*<C>
+#
+--format=gnu-v3 --no-params
+_ZN1AcvT_IiEI1CEEv
+A::operator C<int><C>()
+A::operator C<int><C>
+2013-11-29 Matthias Klose <doko@ubuntu.com>
+
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_FreetypeGlyphVector.c,
+ native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontPeer.c:
+ Fix freetype includes.
+
2013-04-16 Andreas Schwab <schwab@suse.de>
* native/fdlibm/ieeefp.h: Add support for aarch64.
#include <pango/pango.h>
#include <pango/pangoft2.h>
#include <pango/pangofc-font.h>
-#include <freetype/ftglyph.h>
-#include <freetype/ftoutln.h>
+#include <ft2build.h>
+#include FT_GLYPH_H
+#include FT_OUTLINE_H
#include "jcl.h"
#include "gdkfont.h"
#include "gnu_java_awt_peer_gtk_FreetypeGlyphVector.h"
#include <pango/pango.h>
#include <pango/pangoft2.h>
#include <pango/pangofc-font.h>
-#include <freetype/ftglyph.h>
-#include <freetype/ftoutln.h>
-#include <freetype/fttypes.h>
-#include <freetype/tttables.h>
+#include <ft2build.h>
+#include FT_GLYPH_H
+#include FT_OUTLINE_H
+#include FT_TYPES_H
+#include FT_TRUETYPE_TABLES_H
#include "gdkfont.h"
#include "gtkpeer.h"
#include "gnu_java_awt_peer_gtk_GdkFontPeer.h"
+2013-12-04 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * Makefile.am (AM_CPPFLAGS): Define.
+ * Makefile.in: Regenerate.
+ * printf/gmp-impl.h: Remove path from longlong.h include.
+
2013-09-20 Alan Modra <amodra@gmail.com>
* configure: Regenerate.
## Skip over everything if the quadlib is not available:
if BUILD_LIBQUADMATH
ACLOCAL_AMFLAGS = -I .. -I ../config
+AM_CPPFLAGS = -I $(top_srcdir)/../include
## May be used by toolexeclibdir.
gcc_version := $(shell cat $(top_srcdir)/../gcc/BASE-VER)
top_srcdir = @top_srcdir@
AUTOMAKE_OPTIONS = 1.8 foreign
@BUILD_LIBQUADMATH_TRUE@ACLOCAL_AMFLAGS = -I .. -I ../config
+@BUILD_LIBQUADMATH_TRUE@AM_CPPFLAGS = -I $(top_srcdir)/../include
@BUILD_LIBQUADMATH_TRUE@gcc_version := $(shell cat $(top_srcdir)/../gcc/BASE-VER)
@BUILD_LIBQUADMATH_TRUE@@LIBQUAD_USE_SYMVER_FALSE@version_arg =
@BUILD_LIBQUADMATH_TRUE@@LIBQUAD_USE_SYMVER_GNU_TRUE@@LIBQUAD_USE_SYMVER_TRUE@version_arg = -Wl,--version-script=$(srcdir)/quadmath.map
#define attribute_hidden
#endif
-#include "../../libgcc/longlong.h"
+#include "longlong.h"
/* Copy NLIMBS *limbs* from SRC to DST. */
#define MPN_COPY_INCR(DST, SRC, NLIMBS) \
+2013-11-29 Jakub Jelinek <jakub@redhat.com>
+ Yury Gribov <y.gribov@samsung.com>
+
+ PR sanitizer/59063
+ * libsanitizer.spec.in: Add spec file to hold link flags for
+ various sanitizer libs.
+ * configure.ac: Check whether clock_* routines come from librt.
+ * asan/Makefile.am (libasan_la_LDFLAGS): Libs now come from
+ configure.ac.
+ * tsan/Makefile.am (libtsan_la_LDFLAGS): Likewise.
+ * ubsan/Makefile.am (libubsan_la_LDFLAGS): Likewise.
+ * lsan/Makefile.am (liblsan_la_LDFLAGS): Likewise.
+ * asan/Makefile.in: Regenerate.
+ * interception/Makefile.in: Regenerate.
+ * lsan/Makefile.in: Regenerate.
+ * sanitizer_common/Makefile.in: Regenerate.
+ * tsan/Makefile.in: Regenerate.
+ * ubsan/Makefile.in: Regenerate.
+ * Makefile.in: Regenerate.
+ * configure: Regenerate.
+
+2013-11-28 Jakub Jelinek <jakub@redhat.com>
+ Yury Gribov <y.gribov@samsung.com>
+
+ PR sanitizer/59106
+ * ubsan/Makefile.am (AM_CXXFLAGS): Disable -frtti for files that
+ don't need it.
+ * ubsan/Makefile.in: Regenerated.
+
+2013-11-22 Jakub Jelinek <jakub@redhat.com>
+
+ PR sanitizer/59061
+ * configure.tgt: Set LSAN_SUPPORTED=yes for x86_64-linux.
+ * configure.ac (LSAN_SUPPORTED): New AM_CONDITIONAL.
+ * configure: Regenerated.
+ * lsan/Makefile.am (toolexeclib_LTLIBRARIES, lsan_files,
+ liblsan_la_SOURCES, liblsan_la_LIBADD, liblsan_la_LDFLAGS): Add.
+ * lsan/Makefile.in: Regenerated.
+
+2013-11-22 Mike Stump <mikestump@comcast.net>
+
+ * sanitizer_common/sanitizer_linux.cc (__sanitizer): Grab one
+ change from upstream to fix build.
+
2013-11-18 Yury Gribov <y.gribov@samsung.com>
PR sanitizer/59106
MAKEOVERRIDES=
+nodist_toolexeclib_HEADERS = libsanitizer.spec
+
## ################################################################
# PARTICULAR PURPOSE.
@SET_MAKE@
+
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
subdir = .
DIST_COMMON = ChangeLog $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(top_srcdir)/configure $(am__configure_deps) \
- $(srcdir)/../mkinstalldirs
+ $(srcdir)/../mkinstalldirs $(srcdir)/libsanitizer.spec.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \
$(top_srcdir)/../config/depstand.m4 \
am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
configure.lineno config.status.lineno
mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
-CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_FILES = libsanitizer.spec
CONFIG_CLEAN_VPATH_FILES =
SOURCES =
MULTISRCTOP =
install-pdf-recursive install-ps-recursive install-recursive \
installcheck-recursive installdirs-recursive pdf-recursive \
ps-recursive uninstall-recursive
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__installdirs = "$(DESTDIR)$(toolexeclibdir)"
+HEADERS = $(nodist_toolexeclib_HEADERS)
RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
distclean-recursive maintainer-clean-recursive
AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
+link_libasan = @link_libasan@
+link_liblsan = @link_liblsan@
+link_libtsan = @link_libtsan@
+link_libubsan = @link_libubsan@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
"DESTDIR=$(DESTDIR)"
MAKEOVERRIDES =
+nodist_toolexeclib_HEADERS = libsanitizer.spec
all: all-recursive
.SUFFIXES:
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
$(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
$(am__aclocal_m4_deps):
+libsanitizer.spec: $(top_builddir)/config.status $(srcdir)/libsanitizer.spec.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
mostlyclean-libtool:
-rm -f *.lo
$(MULTICLEAN) $(AM_MAKEFLAGS) DO=distclean multi-clean # $(MAKE)
maintainer-clean-multi:
$(MULTICLEAN) $(AM_MAKEFLAGS) DO=maintainer-clean multi-clean # $(MAKE)
+install-nodist_toolexeclibHEADERS: $(nodist_toolexeclib_HEADERS)
+ @$(NORMAL_INSTALL)
+ test -z "$(toolexeclibdir)" || $(MKDIR_P) "$(DESTDIR)$(toolexeclibdir)"
+ @list='$(nodist_toolexeclib_HEADERS)'; test -n "$(toolexeclibdir)" || list=; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(toolexeclibdir)'"; \
+ $(INSTALL_HEADER) $$files "$(DESTDIR)$(toolexeclibdir)" || exit $$?; \
+ done
+
+uninstall-nodist_toolexeclibHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(nodist_toolexeclib_HEADERS)'; test -n "$(toolexeclibdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ test -n "$$files" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(toolexeclibdir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(toolexeclibdir)" && rm -f $$files
# This directory's subdirectories are mostly independent; you can cd
# into them and run `make' without going through this Makefile.
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
check-am: all-am
check: check-recursive
-all-am: Makefile all-multi
+all-am: Makefile all-multi $(HEADERS)
installdirs: installdirs-recursive
installdirs-am:
+ for dir in "$(DESTDIR)$(toolexeclibdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
install: install-recursive
install-exec: install-exec-recursive
install-data: install-data-recursive
install-dvi-am:
-install-exec-am: install-multi
+install-exec-am: install-multi install-nodist_toolexeclibHEADERS
install-html: install-html-recursive
ps-am:
-uninstall-am:
+uninstall-am: uninstall-nodist_toolexeclibHEADERS
.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all-multi \
clean-multi ctags-recursive distclean-multi install-am \
install-am install-data install-data-am install-dvi \
install-dvi-am install-exec install-exec-am install-html \
install-html-am install-info install-info-am install-man \
- install-multi install-pdf install-pdf-am install-ps \
- install-ps-am install-strip installcheck installcheck-am \
- installdirs installdirs-am maintainer-clean \
- maintainer-clean-generic maintainer-clean-multi mostlyclean \
- mostlyclean-generic mostlyclean-libtool mostlyclean-multi pdf \
- pdf-am ps ps-am tags tags-recursive uninstall uninstall-am
+ install-multi install-nodist_toolexeclibHEADERS install-pdf \
+ install-pdf-am install-ps install-ps-am install-strip \
+ installcheck installcheck-am installdirs installdirs-am \
+ maintainer-clean maintainer-clean-generic \
+ maintainer-clean-multi mostlyclean mostlyclean-generic \
+ mostlyclean-libtool mostlyclean-multi pdf pdf-am ps ps-am tags \
+ tags-recursive uninstall uninstall-am \
+ uninstall-nodist_toolexeclibHEADERS
# Tell versions [3.59,3.63) of GNU make to not export all variables.
endif
libasan_la_LIBADD += $(LIBSTDCXX_RAW_CXX_LDFLAGS)
-libasan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` -lpthread -ldl
+libasan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(link_libasan)
libasan_preinit.o: asan_preinit.o
cp $< $@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
+link_libasan = @link_libasan@
+link_liblsan = @link_liblsan@
+link_libtsan = @link_libtsan@
+link_libubsan = @link_libubsan@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
@USING_MAC_INTERPOSE_TRUE@libasan_la_LIBADD = $(top_builddir)/sanitizer_common/libsanitizer_common.la \
@USING_MAC_INTERPOSE_TRUE@ $(top_builddir)/lsan/libsanitizer_lsan.la \
@USING_MAC_INTERPOSE_TRUE@ $(LIBSTDCXX_RAW_CXX_LDFLAGS)
-libasan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` -lpthread -ldl
+libasan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(link_libasan)
# Work around what appears to be a GNU make bug handling MAKEFLAGS
# values defined in terms of make variables, as is the case for CC and
LIBOBJS
USING_MAC_INTERPOSE_FALSE
USING_MAC_INTERPOSE_TRUE
+link_liblsan
+link_libubsan
+link_libtsan
+link_libasan
+LSAN_SUPPORTED_FALSE
+LSAN_SUPPORTED_TRUE
TSAN_SUPPORTED_FALSE
TSAN_SUPPORTED_TRUE
enable_static
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11120 "configure"
+#line 11126 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11226 "configure"
+#line 11232 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
# Get target configury.
unset TSAN_SUPPORTED
+unset LSAN_SUPPORTED
. ${srcdir}/configure.tgt
if test "x$TSAN_SUPPORTED" = "xyes"; then
TSAN_SUPPORTED_TRUE=
TSAN_SUPPORTED_FALSE=
fi
+ if test "x$LSAN_SUPPORTED" = "xyes"; then
+ LSAN_SUPPORTED_TRUE=
+ LSAN_SUPPORTED_FALSE='#'
+else
+ LSAN_SUPPORTED_TRUE='#'
+ LSAN_SUPPORTED_FALSE=
+fi
+
+
+# Check for functions needed.
+for ac_func in clock_getres clock_gettime clock_settime
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+eval as_val=\$$as_ac_var
+ if test "x$as_val" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+# Common libraries that we need to link against for all sanitizer libs.
+link_sanitizer_common='-lpthread -ldl'
+
+# Set up the set of additional libraries that we need to link against for libasan.
+link_libasan=$link_sanitizer_common
+
+
+# Set up the set of additional libraries that we need to link against for libtsan.
+link_libtsan=$link_sanitizer_common
+
+
+# Set up the set of additional libraries that we need to link against for libubsan.
+link_libubsan=$link_sanitizer_common
+
+
+# Set up the set of additional libraries that we need to link against for liblsan.
+link_liblsan=$link_sanitizer_common
+
+
+# At least for glibc, clock_gettime is in librt. But don't pull that
+# in if it still doesn't give us the function we want. This
+# test is copied from libgomp.
+if test $ac_cv_func_clock_gettime = no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for clock_gettime in -lrt" >&5
+$as_echo_n "checking for clock_gettime in -lrt... " >&6; }
+if test "${ac_cv_lib_rt_clock_gettime+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lrt $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char clock_gettime ();
+int
+main ()
+{
+return clock_gettime ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_rt_clock_gettime=yes
+else
+ ac_cv_lib_rt_clock_gettime=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_clock_gettime" >&5
+$as_echo "$ac_cv_lib_rt_clock_gettime" >&6; }
+if test "x$ac_cv_lib_rt_clock_gettime" = x""yes; then :
+ link_libasan="-lrt $link_libasan"
+link_libtsan="-lrt $link_libtsan"
+# Other sanitizers do not override clock_* API
+
+fi
+
+fi
case "$host" in
*-*-darwin*) MAC_INTERPOSE=true ; enable_static=no ;;
fi
-ac_config_files="$ac_config_files Makefile"
+ac_config_files="$ac_config_files Makefile libsanitizer.spec"
ac_config_files="$ac_config_files interception/Makefile sanitizer_common/Makefile lsan/Makefile asan/Makefile ubsan/Makefile"
as_fn_error "conditional \"TSAN_SUPPORTED\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
+if test -z "${LSAN_SUPPORTED_TRUE}" && test -z "${LSAN_SUPPORTED_FALSE}"; then
+ as_fn_error "conditional \"LSAN_SUPPORTED\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
if test -z "${USING_MAC_INTERPOSE_TRUE}" && test -z "${USING_MAC_INTERPOSE_FALSE}"; then
as_fn_error "conditional \"USING_MAC_INTERPOSE\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
"depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
"libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;;
"Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+ "libsanitizer.spec") CONFIG_FILES="$CONFIG_FILES libsanitizer.spec" ;;
"interception/Makefile") CONFIG_FILES="$CONFIG_FILES interception/Makefile" ;;
"sanitizer_common/Makefile") CONFIG_FILES="$CONFIG_FILES sanitizer_common/Makefile" ;;
"lsan/Makefile") CONFIG_FILES="$CONFIG_FILES lsan/Makefile" ;;
# Get target configury.
unset TSAN_SUPPORTED
+unset LSAN_SUPPORTED
. ${srcdir}/configure.tgt
AM_CONDITIONAL(TSAN_SUPPORTED, [test "x$TSAN_SUPPORTED" = "xyes"])
+AM_CONDITIONAL(LSAN_SUPPORTED, [test "x$LSAN_SUPPORTED" = "xyes"])
+
+# Check for functions needed.
+AC_CHECK_FUNCS(clock_getres clock_gettime clock_settime)
+
+# Common libraries that we need to link against for all sanitizer libs.
+link_sanitizer_common='-lpthread -ldl'
+
+# Set up the set of additional libraries that we need to link against for libasan.
+link_libasan=$link_sanitizer_common
+AC_SUBST(link_libasan)
+
+# Set up the set of additional libraries that we need to link against for libtsan.
+link_libtsan=$link_sanitizer_common
+AC_SUBST(link_libtsan)
+
+# Set up the set of additional libraries that we need to link against for libubsan.
+link_libubsan=$link_sanitizer_common
+AC_SUBST(link_libubsan)
+
+# Set up the set of additional libraries that we need to link against for liblsan.
+link_liblsan=$link_sanitizer_common
+AC_SUBST(link_liblsan)
+
+# At least for glibc, clock_gettime is in librt. But don't pull that
+# in if it still doesn't give us the function we want. This
+# test is copied from libgomp.
+if test $ac_cv_func_clock_gettime = no; then
+ AC_CHECK_LIB(rt, clock_gettime,
+ [link_libasan="-lrt $link_libasan"
+link_libtsan="-lrt $link_libtsan"
+# Other sanitizers do not override clock_* API
+])
+fi
case "$host" in
*-*-darwin*) MAC_INTERPOSE=true ; enable_static=no ;;
esac
AM_CONDITIONAL(USING_MAC_INTERPOSE, $MAC_INTERPOSE)
-AC_CONFIG_FILES([Makefile])
+AC_CONFIG_FILES([Makefile libsanitizer.spec])
AC_CONFIG_FILES(AC_FOREACH([DIR], [interception sanitizer_common lsan asan ubsan], [DIR/Makefile ]),
[cat > vpsed$$ << \_EOF
x86_64-*-linux* | i?86-*-linux*)
if test x$ac_cv_sizeof_void_p = x8; then
TSAN_SUPPORTED=yes
+ LSAN_SUPPORTED=yes
fi
;;
powerpc*-*-linux*)
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
+link_libasan = @link_libasan@
+link_liblsan = @link_liblsan@
+link_libtsan = @link_libtsan@
+link_libubsan = @link_libubsan@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
--- /dev/null
+# This spec file is read by gcc when linking. It is used to specify the
+# standard libraries we need in order to link with various sanitizer libs.
+
+*link_libasan: @link_libasan@
+
+*link_libtsan: @link_libtsan@
+
+*link_libubsan: @link_libubsan@
+
+*link_liblsan: @link_liblsan@
+
ACLOCAL_AMFLAGS = -I m4
noinst_LTLIBRARIES = libsanitizer_lsan.la
+if LSAN_SUPPORTED
+toolexeclib_LTLIBRARIES = liblsan.la
+endif
sanitizer_lsan_files = \
lsan_common.cc \
lsan_common_linux.cc
+lsan_files = \
+ $(sanitizer_lsan_files) \
+ lsan.cc \
+ lsan_allocator.cc \
+ lsan_interceptors.cc \
+ lsan_thread.cc
+
libsanitizer_lsan_la_SOURCES = $(sanitizer_lsan_files)
+liblsan_la_SOURCES = $(lsan_files)
+liblsan_la_LIBADD = $(top_builddir)/sanitizer_common/libsanitizer_common.la $(top_builddir)/interception/libinterception.la $(LIBSTDCXX_RAW_CXX_LDFLAGS)
+liblsan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(link_liblsan)
+
# Work around what appears to be a GNU make bug handling MAKEFLAGS
# values defined in terms of make variables, as is the case for CC and
# friends when we are called from the top level Makefile.
mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
-LTLIBRARIES = $(noinst_LTLIBRARIES)
-libsanitizer_lsan_la_LIBADD =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__installdirs = "$(DESTDIR)$(toolexeclibdir)"
+LTLIBRARIES = $(noinst_LTLIBRARIES) $(toolexeclib_LTLIBRARIES)
+am__DEPENDENCIES_1 =
+liblsan_la_DEPENDENCIES = \
+ $(top_builddir)/sanitizer_common/libsanitizer_common.la \
+ $(top_builddir)/interception/libinterception.la \
+ $(am__DEPENDENCIES_1)
am__objects_1 = lsan_common.lo lsan_common_linux.lo
+am__objects_2 = $(am__objects_1) lsan.lo lsan_allocator.lo \
+ lsan_interceptors.lo lsan_thread.lo
+am_liblsan_la_OBJECTS = $(am__objects_2)
+liblsan_la_OBJECTS = $(am_liblsan_la_OBJECTS)
+liblsan_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+ $(CXXFLAGS) $(liblsan_la_LDFLAGS) $(LDFLAGS) -o $@
+@LSAN_SUPPORTED_TRUE@am_liblsan_la_rpath = -rpath $(toolexeclibdir)
+libsanitizer_lsan_la_LIBADD =
am_libsanitizer_lsan_la_OBJECTS = $(am__objects_1)
libsanitizer_lsan_la_OBJECTS = $(am_libsanitizer_lsan_la_OBJECTS)
DEFAULT_INCLUDES = -I.@am__isrc@
CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
$(LDFLAGS) -o $@
-SOURCES = $(libsanitizer_lsan_la_SOURCES)
+SOURCES = $(liblsan_la_SOURCES) $(libsanitizer_lsan_la_SOURCES)
ETAGS = etags
CTAGS = ctags
ACLOCAL = @ACLOCAL@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
+link_libasan = @link_libasan@
+link_liblsan = @link_liblsan@
+link_libtsan = @link_libtsan@
+link_libubsan = @link_libubsan@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
-Wno-variadic-macros $(LIBSTDCXX_RAW_CXX_CXXFLAGS)
ACLOCAL_AMFLAGS = -I m4
noinst_LTLIBRARIES = libsanitizer_lsan.la
+@LSAN_SUPPORTED_TRUE@toolexeclib_LTLIBRARIES = liblsan.la
sanitizer_lsan_files = \
lsan_common.cc \
lsan_common_linux.cc
+lsan_files = \
+ $(sanitizer_lsan_files) \
+ lsan.cc \
+ lsan_allocator.cc \
+ lsan_interceptors.cc \
+ lsan_thread.cc
+
libsanitizer_lsan_la_SOURCES = $(sanitizer_lsan_files)
+liblsan_la_SOURCES = $(lsan_files)
+liblsan_la_LIBADD = $(top_builddir)/sanitizer_common/libsanitizer_common.la $(top_builddir)/interception/libinterception.la $(LIBSTDCXX_RAW_CXX_LDFLAGS)
+liblsan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(link_liblsan)
# Work around what appears to be a GNU make bug handling MAKEFLAGS
# values defined in terms of make variables, as is the case for CC and
echo "rm -f \"$${dir}/so_locations\""; \
rm -f "$${dir}/so_locations"; \
done
+install-toolexeclibLTLIBRARIES: $(toolexeclib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(toolexeclibdir)" || $(MKDIR_P) "$(DESTDIR)$(toolexeclibdir)"
+ @list='$(toolexeclib_LTLIBRARIES)'; test -n "$(toolexeclibdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(toolexeclibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(toolexeclibdir)"; \
+ }
+
+uninstall-toolexeclibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(toolexeclib_LTLIBRARIES)'; test -n "$(toolexeclibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(toolexeclibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(toolexeclibdir)/$$f"; \
+ done
+
+clean-toolexeclibLTLIBRARIES:
+ -test -z "$(toolexeclib_LTLIBRARIES)" || rm -f $(toolexeclib_LTLIBRARIES)
+ @list='$(toolexeclib_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+liblsan.la: $(liblsan_la_OBJECTS) $(liblsan_la_DEPENDENCIES)
+ $(liblsan_la_LINK) $(am_liblsan_la_rpath) $(liblsan_la_OBJECTS) $(liblsan_la_LIBADD) $(LIBS)
libsanitizer_lsan.la: $(libsanitizer_lsan_la_OBJECTS) $(libsanitizer_lsan_la_DEPENDENCIES)
$(CXXLINK) $(libsanitizer_lsan_la_OBJECTS) $(libsanitizer_lsan_la_LIBADD) $(LIBS)
distclean-compile:
-rm -f *.tab.c
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lsan.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lsan_allocator.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lsan_common.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lsan_common_linux.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lsan_interceptors.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lsan_thread.Plo@am__quote@
.cc.o:
@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
check: check-am
all-am: Makefile $(LTLIBRARIES)
installdirs:
+ for dir in "$(DESTDIR)$(toolexeclibdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
clean: clean-am
clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
- mostlyclean-am
+ clean-toolexeclibLTLIBRARIES mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
install-dvi-am:
-install-exec-am:
+install-exec-am: install-toolexeclibLTLIBRARIES
install-html: install-html-am
ps-am:
-uninstall-am:
+uninstall-am: uninstall-toolexeclibLTLIBRARIES
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
- clean-libtool clean-noinstLTLIBRARIES ctags distclean \
- distclean-compile distclean-generic distclean-libtool \
- distclean-tags dvi dvi-am html html-am info info-am install \
- install-am install-data install-data-am install-dvi \
- install-dvi-am install-exec install-exec-am install-html \
- install-html-am install-info install-info-am install-man \
- install-pdf install-pdf-am install-ps install-ps-am \
- install-strip installcheck installcheck-am installdirs \
- maintainer-clean maintainer-clean-generic mostlyclean \
- mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
- pdf pdf-am ps ps-am tags uninstall uninstall-am
+ clean-libtool clean-noinstLTLIBRARIES \
+ clean-toolexeclibLTLIBRARIES ctags distclean distclean-compile \
+ distclean-generic distclean-libtool distclean-tags dvi dvi-am \
+ html html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip \
+ install-toolexeclibLTLIBRARIES installcheck installcheck-am \
+ installdirs maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \
+ uninstall-am uninstall-toolexeclibLTLIBRARIES
# Tell versions [3.59,3.63) of GNU make to not export all variables.
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
+link_libasan = @link_libasan@
+link_liblsan = @link_liblsan@
+link_libtsan = @link_libtsan@
+link_libubsan = @link_libubsan@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
* %r8 = new_tls,
* %r10 = child_tidptr)
*/
- ".cfi_endproc\n"
"syscall\n"
/* if (%rax != 0)
"jnz 1f\n"
/* In the child. Terminate unwind chain. */
- ".cfi_startproc\n"
- ".cfi_undefined %%rip;\n"
+ // XXX: We should also terminate the CFI unwind chain
+ // here. Unfortunately clang 3.2 doesn't support the
+ // necessary CFI directives, so we skip that part.
"xorq %%rbp,%%rbp\n"
/* Call "fn(arg)". */
libtsan_la_SOURCES = $(tsan_files)
libtsan_la_LIBADD = $(top_builddir)/sanitizer_common/libsanitizer_common.la $(top_builddir)/interception/libinterception.la $(LIBSTDCXX_RAW_CXX_LDFLAGS)
-libtsan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` -lpthread -ldl
+libtsan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(link_libtsan)
# Work around what appears to be a GNU make bug handling MAKEFLAGS
# values defined in terms of make variables, as is the case for CC and
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
+link_libasan = @link_libasan@
+link_liblsan = @link_liblsan@
+link_libtsan = @link_libtsan@
+link_libubsan = @link_libubsan@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
libtsan_la_SOURCES = $(tsan_files)
libtsan_la_LIBADD = $(top_builddir)/sanitizer_common/libsanitizer_common.la $(top_builddir)/interception/libinterception.la $(LIBSTDCXX_RAW_CXX_LDFLAGS)
-libtsan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` -lpthread -ldl
+libtsan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(link_libtsan)
# Work around what appears to be a GNU make bug handling MAKEFLAGS
# values defined in terms of make variables, as is the case for CC and
gcc_version := $(shell cat $(top_srcdir)/../gcc/BASE-VER)
DEFS = -D_GNU_SOURCE -D_DEBUG -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
-AM_CXXFLAGS = -Wall -W -Wno-unused-parameter -Wwrite-strings -pedantic -Wno-long-long -fPIC -fno-builtin -fno-exceptions -fomit-frame-pointer -funwind-tables -fvisibility=hidden -Wno-variadic-macros
+AM_CXXFLAGS = -Wall -W -Wno-unused-parameter -Wwrite-strings -pedantic -Wno-long-long -fPIC -fno-builtin -fno-exceptions -fno-rtti -fomit-frame-pointer -funwind-tables -fvisibility=hidden -Wno-variadic-macros
AM_CXXFLAGS += $(LIBSTDCXX_RAW_CXX_CXXFLAGS)
ACLOCAL_AMFLAGS = -I m4
libubsan_la_LIBADD += $(top_builddir)/interception/libinterception.la
endif
libubsan_la_LIBADD += $(LIBSTDCXX_RAW_CXX_LDFLAGS)
-libubsan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` -lpthread -ldl
+libubsan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(link_libubsan)
+
+# Use special rules for files that require RTTI support.
+ubsan_handlers_cxx.% ubsan_type_hash.% : AM_CXXFLAGS += -frtti
# Work around what appears to be a GNU make bug handling MAKEFLAGS
# values defined in terms of make variables, as is the case for CC and
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
+link_libasan = @link_libasan@
+link_liblsan = @link_liblsan@
+link_libtsan = @link_libtsan@
+link_libubsan = @link_libubsan@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
# May be used by toolexeclibdir.
gcc_version := $(shell cat $(top_srcdir)/../gcc/BASE-VER)
AM_CXXFLAGS = -Wall -W -Wno-unused-parameter -Wwrite-strings -pedantic \
- -Wno-long-long -fPIC -fno-builtin -fno-exceptions \
+ -Wno-long-long -fPIC -fno-builtin -fno-exceptions -fno-rtti \
-fomit-frame-pointer -funwind-tables -fvisibility=hidden \
-Wno-variadic-macros $(LIBSTDCXX_RAW_CXX_CXXFLAGS)
ACLOCAL_AMFLAGS = -I m4
libubsan_la_LIBADD = \
$(top_builddir)/sanitizer_common/libsanitizer_common.la \
$(am__append_1) $(LIBSTDCXX_RAW_CXX_LDFLAGS)
-libubsan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` -lpthread -ldl
+libubsan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(link_libubsan)
# Work around what appears to be a GNU make bug handling MAKEFLAGS
# values defined in terms of make variables, as is the case for CC and
tags uninstall uninstall-am uninstall-toolexeclibLTLIBRARIES
+# Use special rules for files that require RTTI support.
+ubsan_handlers_cxx.% ubsan_type_hash.% : AM_CXXFLAGS += -frtti
+
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
+2013-12-03 Jonathan Wakely <jwakely.gcc@gmail.com>
+
+ * include/std/fstream (basic_filebuf::open): Use preformatted text
+ for table in Doxygen comment.
+
+2013-12-03 Tim Shen <timshen91@gmail.com>
+
+ * regex_compiler.h: Add todo comment.
+ * regex_executor.tcc: Likewise.
+
+2013-11-29 Matthias Klose <doko@ubuntu.com>
+
+ * testsuite/experimental/string_view/requirements/exception,
+ testsuite/experimental/string_view/capacity/wchar_t,
+ testsuite/experimental/string_view/capacity/char: Remove empty dirs.
+
+2013-11-27 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ * testsuite/ext/random/hypergeometric_distribution/operators/values.cc:
+ Use dg-require-cmath instead.
+
+ * testsuite/ext/random/hypergeometric_distribution/operators/values.cc
+ (test01): Wrap in _GLIBCXX_USE_C99_MATH_TR1.
+
+2013-11-22 François Dumont <fdumont@gcc.gnu.org>
+
+ * include/debug/safe_local_iterator.h (_Safe_local_iterator<>):
+ Remove _M_bucket, use same information in normal local_iterator.
+ (operator==): Remove redundant _M_can_compare check.
+ * include/debug/safe_local_iterator.tcc: Adapt.
+ * include/debug/unordered_set: Likewise.
+ * include/debug/unordered_map: Likewise.
+
+2013-11-22 Jakub Jelinek <jakub@redhat.com>
+
+ * testsuite/Makefile.am (check_DEJAGNU_normal_targets): Add 10.
+ (check-DEJAGNU): Add normal10, run 28_regex/[ab]*
+ tests as another separate job.
+ * testsuite/Makefile.in: Regenerated.
+
2013-11-22 Jonathan Wakely <jwakely.gcc@gmail.com>
* acinclude.m4 (libtool_VERSION): Bump.
* configure: Regenerate.
* doc/xml/manual/abi.xml: Update version information.
+ PR libstdc++/59247
+ * include/bits/c++config (_GLIBCXX_INLINE_VERSION): Declare namespace
+ std::experimental::__7 as inline.
+ * include/bits/regex.h (_GLIBCXX_BEGIN_NAMESPACE_VERSION): Do not
+ enclose namespace __detail.
+ * include/bits/regex.tcc (_GLIBCXX_BEGIN_NAMESPACE_VERSION): Likewise.
+ * include/std/iomanip (_GLIBCXX_BEGIN_NAMESPACE_VERSION): Likewise.
+ * include/ext/pb_ds/tag_and_trait.hpp (detail): Fix comment.
+ * testsuite/ext/profile/mutex_extensions_neg.cc: Adjust line number.
+
2013-11-22 Paolo Carlini <paolo.carlini@oracle.com>
* testsuite/ext/random/hypergeometric_distribution/operators/
namespace placeholders { }
namespace regex_constants { }
namespace this_thread { }
+
+ namespace experimental { }
}
namespace abi { }
namespace regex_constants { inline namespace __7 { } }
namespace this_thread { inline namespace __7 { } }
+ namespace experimental { inline namespace __7 { } }
+
namespace __detail { inline namespace __7 { } }
}
namespace std _GLIBCXX_VISIBILITY(default)
{
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
-
namespace __detail
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
_GLIBCXX_END_NAMESPACE_VERSION
}
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
/**
* @addtogroup regex
* @{
namespace std _GLIBCXX_VISIBILITY(default)
{
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
-
namespace __detail
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
_GLIBCXX_END_NAMESPACE_VERSION
}
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
template<typename _Ch_type>
template<typename _Fwd_iter>
typename regex_traits<_Ch_type>::string_type
};
/// Matches a character range (bracket expression)
+ // TODO: Convert used _M_flags fields to template parameters, including
+ // collate and icase. Avoid using std::set, could use flat_set
+ // (sorted vector and binary search) instead; use an fixed sized (256)
+ // vector<bool> for char specialization if necessary.
template<typename _TraitsT>
struct _BracketMatcher
{
return false;
}
+ // TODO: Use a function vector to dispatch, instead of using switch-case.
template<typename _BiIter, typename _Alloc, typename _TraitsT,
bool __dfs_mode>
template<bool __match_mode>
/// The underlying iterator
_Iterator _M_current;
- /// The bucket this local iterator belongs to
- size_type _M_bucket;
-
/// Determine if this is a constant iterator.
bool
_M_constant() const
* @pre @p seq is not NULL
* @post this is not singular
*/
- _Safe_local_iterator(const _Iterator& __i, size_type __bucket,
- const _Sequence* __seq)
- : _Safe_local_iterator_base(__seq, _M_constant()), _M_current(__i),
- _M_bucket(__bucket)
+ _Safe_local_iterator(const _Iterator& __i, const _Sequence* __seq)
+ : _Safe_local_iterator_base(__seq, _M_constant()), _M_current(__i)
{
_GLIBCXX_DEBUG_VERIFY(!this->_M_singular(),
_M_message(__msg_init_singular)
*/
_Safe_local_iterator(const _Safe_local_iterator& __x)
: _Safe_local_iterator_base(__x, _M_constant()),
- _M_current(__x._M_current), _M_bucket(__x._M_bucket)
+ _M_current(__x._M_current)
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 408. Is vector<reverse_iterator<char*> > forbidden?
_GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
- || __x._M_current == _Iterator(),
+ || __x.base() == _Iterator(),
_M_message(__msg_init_copy_singular)
._M_iterator(*this, "this")
._M_iterator(__x, "other"));
typename _Sequence::local_iterator::iterator_type>::__value,
_Sequence>::__type>& __x)
: _Safe_local_iterator_base(__x, _M_constant()),
- _M_current(__x.base()), _M_bucket(__x._M_bucket)
+ _M_current(__x.base())
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 408. Is vector<reverse_iterator<char*> > forbidden?
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 408. Is vector<reverse_iterator<char*> > forbidden?
_GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
- || __x._M_current == _Iterator(),
+ || __x.base() == _Iterator(),
_M_message(__msg_copy_singular)
._M_iterator(*this, "this")
._M_iterator(__x, "other"));
_M_current = __x._M_current;
- _M_bucket = __x._M_bucket;
this->_M_attach(__x._M_sequence);
return *this;
}
* @brief Return the bucket
*/
size_type
- bucket() const { return _M_bucket; }
+ bucket() const { return _M_current._M_bucket; }
/**
* @brief Conversion to underlying non-debug iterator to allow
_M_get_sequence() const
{ return static_cast<_Sequence*>(_M_sequence); }
- /// Is this iterator equal to the sequence's begin() iterator?
+ /// Is this iterator equal to the sequence's begin(bucket) iterator?
bool _M_is_begin() const
- { return base() == _M_get_sequence()->_M_base().begin(_M_bucket); }
+ { return base() == _M_get_sequence()->_M_base().begin(bucket()); }
- /// Is this iterator equal to the sequence's end() iterator?
+ /// Is this iterator equal to the sequence's end(bucket) iterator?
bool _M_is_end() const
- { return base() == _M_get_sequence()->_M_base().end(_M_bucket); }
+ { return base() == _M_get_sequence()->_M_base().end(bucket()); }
/// Is this iterator part of the same bucket as the other one?
- template <typename _Other>
- bool _M_in_same_bucket(const _Safe_local_iterator<_Other,
- _Sequence>& __other) const
- { return _M_bucket == __other.bucket(); }
+ template<typename _Other>
+ bool
+ _M_in_same_bucket(const _Safe_local_iterator<_Other,
+ _Sequence>& __other) const
+ { return bucket() == __other.bucket(); }
};
template<typename _IteratorL, typename _IteratorR, typename _Sequence>
operator==(const _Safe_local_iterator<_IteratorL, _Sequence>& __lhs,
const _Safe_local_iterator<_IteratorR, _Sequence>& __rhs)
{
- _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
+ _GLIBCXX_DEBUG_VERIFY(!__lhs._M_singular() && !__rhs._M_singular(),
_M_message(__msg_iter_compare_bad)
._M_iterator(__lhs, "lhs")
._M_iterator(__rhs, "rhs"));
_M_message(__msg_compare_different)
._M_iterator(__lhs, "lhs")
._M_iterator(__rhs, "rhs"));
- _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
- _M_message(__msg_compare_different)
- ._M_iterator(__lhs, "lhs")
- ._M_iterator(__rhs, "rhs"));
_GLIBCXX_DEBUG_VERIFY(__lhs._M_in_same_bucket(__rhs),
_M_message(__msg_local_iter_compare_bad)
._M_iterator(__lhs, "lhs")
operator==(const _Safe_local_iterator<_Iterator, _Sequence>& __lhs,
const _Safe_local_iterator<_Iterator, _Sequence>& __rhs)
{
- _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
+ _GLIBCXX_DEBUG_VERIFY(!__lhs._M_singular() && !__rhs._M_singular(),
_M_message(__msg_iter_compare_bad)
._M_iterator(__lhs, "lhs")
._M_iterator(__rhs, "rhs"));
operator!=(const _Safe_local_iterator<_Iterator, _Sequence>& __lhs,
const _Safe_local_iterator<_Iterator, _Sequence>& __rhs)
{
- _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
+ _GLIBCXX_DEBUG_VERIFY(!__lhs._M_singular() && !__rhs._M_singular(),
_M_message(__msg_iter_compare_bad)
._M_iterator(__lhs, "lhs")
._M_iterator(__rhs, "rhs"));
{
if (!_M_can_compare(__rhs))
return false;
- if (_M_bucket != __rhs._M_bucket)
+ if (bucket() != __rhs.bucket())
return false;
/* Determine if we can order the iterators without the help of
begin(size_type __b)
{
__glibcxx_check_bucket_index(__b);
- return local_iterator(_Base::begin(__b), __b, this);
+ return local_iterator(_Base::begin(__b), this);
}
local_iterator
end(size_type __b)
{
__glibcxx_check_bucket_index(__b);
- return local_iterator(_Base::end(__b), __b, this);
+ return local_iterator(_Base::end(__b), this);
}
const_local_iterator
begin(size_type __b) const
{
__glibcxx_check_bucket_index(__b);
- return const_local_iterator(_Base::begin(__b), __b, this);
+ return const_local_iterator(_Base::begin(__b), this);
}
const_local_iterator
end(size_type __b) const
{
__glibcxx_check_bucket_index(__b);
- return const_local_iterator(_Base::end(__b), __b, this);
+ return const_local_iterator(_Base::end(__b), this);
}
const_local_iterator
cbegin(size_type __b) const
{
__glibcxx_check_bucket_index(__b);
- return const_local_iterator(_Base::cbegin(__b), __b, this);
+ return const_local_iterator(_Base::cbegin(__b), this);
}
const_local_iterator
cend(size_type __b) const
{
__glibcxx_check_bucket_index(__b);
- return const_local_iterator(_Base::cend(__b), __b, this);
+ return const_local_iterator(_Base::cend(__b), this);
}
size_type
begin(size_type __b)
{
__glibcxx_check_bucket_index(__b);
- return local_iterator(_Base::begin(__b), __b, this);
+ return local_iterator(_Base::begin(__b), this);
}
local_iterator
end(size_type __b)
{
__glibcxx_check_bucket_index(__b);
- return local_iterator(_Base::end(__b), __b, this);
+ return local_iterator(_Base::end(__b), this);
}
const_local_iterator
begin(size_type __b) const
{
__glibcxx_check_bucket_index(__b);
- return const_local_iterator(_Base::begin(__b), __b, this);
+ return const_local_iterator(_Base::begin(__b), this);
}
const_local_iterator
end(size_type __b) const
{
__glibcxx_check_bucket_index(__b);
- return const_local_iterator(_Base::end(__b), __b, this);
+ return const_local_iterator(_Base::end(__b), this);
}
const_local_iterator
cbegin(size_type __b) const
{
__glibcxx_check_bucket_index(__b);
- return const_local_iterator(_Base::cbegin(__b), __b, this);
+ return const_local_iterator(_Base::cbegin(__b), this);
}
const_local_iterator
cend(size_type __b) const
{
__glibcxx_check_bucket_index(__b);
- return const_local_iterator(_Base::cend(__b), __b, this);
+ return const_local_iterator(_Base::cend(__b), this);
}
size_type
begin(size_type __b)
{
__glibcxx_check_bucket_index(__b);
- return local_iterator(_Base::begin(__b), __b, this);
+ return local_iterator(_Base::begin(__b), this);
}
local_iterator
end(size_type __b)
{
__glibcxx_check_bucket_index(__b);
- return local_iterator(_Base::end(__b), __b, this);
+ return local_iterator(_Base::end(__b), this);
}
const_local_iterator
begin(size_type __b) const
{
__glibcxx_check_bucket_index(__b);
- return const_local_iterator(_Base::begin(__b), __b, this);
+ return const_local_iterator(_Base::begin(__b), this);
}
const_local_iterator
end(size_type __b) const
{
__glibcxx_check_bucket_index(__b);
- return const_local_iterator(_Base::end(__b), __b, this);
+ return const_local_iterator(_Base::end(__b), this);
}
const_local_iterator
cbegin(size_type __b) const
{
__glibcxx_check_bucket_index(__b);
- return const_local_iterator(_Base::cbegin(__b), __b, this);
+ return const_local_iterator(_Base::cbegin(__b), this);
}
const_local_iterator
cend(size_type __b) const
{
__glibcxx_check_bucket_index(__b);
- return const_local_iterator(_Base::cend(__b), __b, this);
+ return const_local_iterator(_Base::cend(__b), this);
}
size_type
begin(size_type __b)
{
__glibcxx_check_bucket_index(__b);
- return local_iterator(_Base::begin(__b), __b, this);
+ return local_iterator(_Base::begin(__b), this);
}
local_iterator
end(size_type __b)
{
__glibcxx_check_bucket_index(__b);
- return local_iterator(_Base::end(__b), __b, this);
+ return local_iterator(_Base::end(__b), this);
}
const_local_iterator
begin(size_type __b) const
{
__glibcxx_check_bucket_index(__b);
- return const_local_iterator(_Base::begin(__b), __b, this);
+ return const_local_iterator(_Base::begin(__b), this);
}
const_local_iterator
end(size_type __b) const
{
__glibcxx_check_bucket_index(__b);
- return const_local_iterator(_Base::end(__b), __b, this);
+ return const_local_iterator(_Base::end(__b), this);
}
const_local_iterator
cbegin(size_type __b) const
{
__glibcxx_check_bucket_index(__b);
- return const_local_iterator(_Base::cbegin(__b), __b, this);
+ return const_local_iterator(_Base::cbegin(__b), this);
}
const_local_iterator
cend(size_type __b) const
{
__glibcxx_check_bucket_index(__b);
- return const_local_iterator(_Base::cend(__b), __b, this);
+ return const_local_iterator(_Base::cend(__b), this);
}
size_type
template<typename Key, typename Mapped, typename _Alloc, typename Tag,
typename Policy_Tl = null_type>
struct container_base_dispatch;
- } // namespace __detail
+ } // namespace detail
//@}
} // namespace __gnu_pbds
* given in @a __mode.
*
* Table 92, adapted here, gives the relation between openmode
- * combinations and the equivalent fopen() flags.
+ * combinations and the equivalent @c fopen() flags.
* (NB: lines app, in|out|app, in|app, binary|app, binary|in|out|app,
* and binary|in|app per DR 596)
+ * <pre>
* +---------------------------------------------------------+
* | ios_base Flag combination stdio equivalent |
* |binary in out trunc app |
* | + + + + a+b |
* | + + + a+b |
* +---------------------------------------------------------+
+ * </pre>
*/
__filebuf_type*
open(const char* __s, ios_base::openmode __mode);
#if __cplusplus > 201103L
+_GLIBCXX_END_NAMESPACE_VERSION
namespace __detail {
+ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @brief Struct for delimited strings.
return __is;
}
-
+ _GLIBCXX_END_NAMESPACE_VERSION
} // namespace __detail
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @brief Manipulator for quoted strings.
@test ! -f $*/site.exp || mv $*/site.exp $*/site.bak
@mv $*/site.exp.tmp $*/site.exp
-check_DEJAGNU_normal_targets = $(patsubst %,check-DEJAGNUnormal%,0 1 2 3 4 5 6 7 8 9)
+check_DEJAGNU_normal_targets = $(patsubst %,check-DEJAGNUnormal%,0 1 2 3 4 5 6 7 8 9 10)
$(check_DEJAGNU_normal_targets): check-DEJAGNUnormal%: normal%/site.exp
# Run the testsuite in normal mode.
if [ -z "$*$(filter-out --target_board=%, $(RUNTESTFLAGS))" ] \
&& [ "$(filter -j, $(MFLAGS))" = "-j" ]; then \
$(MAKE) $(AM_MAKEFLAGS) $(check_DEJAGNU_normal_targets); \
- for idx in 0 1 2 3 4 5 6 7 8 9; do \
+ for idx in 0 1 2 3 4 5 6 7 8 9 10; do \
mv -f normal$$idx/libstdc++.sum normal$$idx/libstdc++.sum.sep; \
mv -f normal$$idx/libstdc++.log normal$$idx/libstdc++.log.sep; \
done; \
mv -f libstdc++.sum libstdc++.sum.sep; \
mv -f libstdc++.log libstdc++.log.sep; \
$(SHELL) $(srcdir)/../../contrib/dg-extract-results.sh \
- libstdc++.sum.sep normal[0-9]/libstdc++.sum.sep > libstdc++.sum; \
+ libstdc++.sum.sep normal[0-9]*/libstdc++.sum.sep > libstdc++.sum; \
$(SHELL) $(srcdir)/../../contrib/dg-extract-results.sh -L \
- libstdc++.log.sep normal[0-9]/libstdc++.log.sep > libstdc++.log; \
+ libstdc++.log.sep normal[0-9]*/libstdc++.log.sep > libstdc++.log; \
exit 0; \
fi; \
srcdir=`$(am__cd) $(srcdir) && pwd`; export srcdir; \
normal6) \
dirs="`cd $$srcdir; echo 2[459]_*/*`";; \
normal7) \
- dirs="`cd $$srcdir; echo 2[68]_*/*`";; \
+ dirs="`cd $$srcdir; echo 26_*/* 28_*/[c-z]*`";; \
normal8) \
dirs="`cd $$srcdir; echo 27_*/*`";; \
normal9) \
+ dirs="`cd $$srcdir; echo 28_*/[ab]*`";; \
+ normal10) \
dirs="`cd $$srcdir; echo t*/*`";; \
esac; \
if [ -n "$*" ]; then cd "$*"; fi; \
extract_symvers = $(glibcxx_builddir)/scripts/extract_symvers
baseline_subdir := $(shell $(CXX) $(baseline_subdir_switch))
-check_DEJAGNU_normal_targets = $(patsubst %,check-DEJAGNUnormal%,0 1 2 3 4 5 6 7 8 9)
+check_DEJAGNU_normal_targets = $(patsubst %,check-DEJAGNUnormal%,0 1 2 3 4 5 6 7 8 9 10)
# Runs the testsuite, but in compile only mode.
# Can be used to test sources with non-GNU FE's at various warning
if [ -z "$*$(filter-out --target_board=%, $(RUNTESTFLAGS))" ] \
&& [ "$(filter -j, $(MFLAGS))" = "-j" ]; then \
$(MAKE) $(AM_MAKEFLAGS) $(check_DEJAGNU_normal_targets); \
- for idx in 0 1 2 3 4 5 6 7 8 9; do \
+ for idx in 0 1 2 3 4 5 6 7 8 9 10; do \
mv -f normal$$idx/libstdc++.sum normal$$idx/libstdc++.sum.sep; \
mv -f normal$$idx/libstdc++.log normal$$idx/libstdc++.log.sep; \
done; \
mv -f libstdc++.sum libstdc++.sum.sep; \
mv -f libstdc++.log libstdc++.log.sep; \
$(SHELL) $(srcdir)/../../contrib/dg-extract-results.sh \
- libstdc++.sum.sep normal[0-9]/libstdc++.sum.sep > libstdc++.sum; \
+ libstdc++.sum.sep normal[0-9]*/libstdc++.sum.sep > libstdc++.sum; \
$(SHELL) $(srcdir)/../../contrib/dg-extract-results.sh -L \
- libstdc++.log.sep normal[0-9]/libstdc++.log.sep > libstdc++.log; \
+ libstdc++.log.sep normal[0-9]*/libstdc++.log.sep > libstdc++.log; \
exit 0; \
fi; \
srcdir=`$(am__cd) $(srcdir) && pwd`; export srcdir; \
normal6) \
dirs="`cd $$srcdir; echo 2[459]_*/*`";; \
normal7) \
- dirs="`cd $$srcdir; echo 2[68]_*/*`";; \
+ dirs="`cd $$srcdir; echo 26_*/* 28_*/[c-z]*`";; \
normal8) \
dirs="`cd $$srcdir; echo 27_*/*`";; \
normal9) \
+ dirs="`cd $$srcdir; echo 28_*/[ab]*`";; \
+ normal10) \
dirs="`cd $$srcdir; echo t*/*`";; \
esac; \
if [ -n "$*" ]; then cd "$*"; fi; \
#include <vector>
-// { dg-error "multiple inlined namespaces" "" { target *-*-* } 275 }
+// { dg-error "multiple inlined namespaces" "" { target *-*-* } 279 }
// { dg-options "-std=gnu++11" }
// { dg-require-cstdint "" }
+// { dg-require-cmath "" }
//
// 2013-11-18 Edward M. Smith-Rowland <3dw4rd@verizon.net>
//
+2013-12-02 Gerald Pfeifer <gerald@pfeifer.com>
+
+ * update_web_docs_svn: Work around makeinfo generated file names
+ and references with "_002d" instead of "-".
+
2013-04-12 Jakub Jelinek <jakub@redhat.com>
* crontab: Disable snapshots from gcc-4_6-branch.
fi
done
+# Work around makeinfo generated file names and references with
+# "_002d" instead of "-".
+find . -name '*.html' | while read f; do
+ # Do this for the contents of each file.
+ sed -i -e 's/_002d/-/g' "$f"
+ # And rename files if necessary.
+ ff=`echo $f | sed -e 's/_002d/-/g'`;
+ if [ "$f" != "$ff" ]; then
+ printf "Renaming %s to %s\n" "$f" "$ff"
+ mv "$f" "$ff"
+ fi
+done
+
# Then build a gzipped copy of each of the resulting .html, .ps and .tar files
for file in */*.html *.ps *.pdf *.tar; do
cat $file | gzip --best > $file.gz