/* Default target hook functions.
- Copyright (C) 2003-2017 Free Software Foundation, Inc.
+ Copyright (C) 2003-2020 Free Software Foundation, Inc.
This file is part of GCC.
#include "opts.h"
#include "gimplify.h"
#include "predict.h"
-#include "params.h"
#include "real.h"
-
+#include "langhooks.h"
+#include "sbitmap.h"
+#include "function-abi.h"
bool
default_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED,
}
bool
-default_legitimize_address_displacement (rtx *disp ATTRIBUTE_UNUSED,
- rtx *offset ATTRIBUTE_UNUSED,
- machine_mode mode ATTRIBUTE_UNUSED)
+default_legitimize_address_displacement (rtx *, rtx *, poly_int64,
+ machine_mode)
+{
+ return false;
+}
+
+bool
+default_const_not_ok_for_debug_p (rtx x)
{
+ if (GET_CODE (x) == UNSPEC)
+ return true;
return false;
}
rtx
default_expand_builtin_saveregs (void)
{
- error ("__builtin_saveregs not supported by this target");
+ error ("%<__builtin_saveregs%> not supported by this target");
return const0_rtx;
}
void
-default_setup_incoming_varargs (cumulative_args_t ca ATTRIBUTE_UNUSED,
- machine_mode mode ATTRIBUTE_UNUSED,
- tree type ATTRIBUTE_UNUSED,
- int *pretend_arg_size ATTRIBUTE_UNUSED,
- int second_time ATTRIBUTE_UNUSED)
+default_setup_incoming_varargs (cumulative_args_t,
+ const function_arg_info &, int *, int)
{
}
unsigned HOST_WIDE_INT
default_shift_truncation_mask (machine_mode mode)
{
- return SHIFT_COUNT_TRUNCATED ? GET_MODE_BITSIZE (mode) - 1 : 0;
+ return SHIFT_COUNT_TRUNCATED ? GET_MODE_UNIT_BITSIZE (mode) - 1 : 0;
}
/* The default implementation of TARGET_MIN_DIVISIONS_FOR_RECIP_MUL. */
of the TARGET_PASS_BY_REFERENCE hook uses just MUST_PASS_IN_STACK. */
bool
-hook_pass_by_reference_must_pass_in_stack (cumulative_args_t c ATTRIBUTE_UNUSED,
- machine_mode mode ATTRIBUTE_UNUSED, const_tree type ATTRIBUTE_UNUSED,
- bool named_arg ATTRIBUTE_UNUSED)
+hook_pass_by_reference_must_pass_in_stack (cumulative_args_t,
+ const function_arg_info &arg)
{
- return targetm.calls.must_pass_in_stack (mode, type);
+ return targetm.calls.must_pass_in_stack (arg);
}
/* Return true if a parameter follows callee copies conventions. This
version of the hook is true for all named arguments. */
bool
-hook_callee_copies_named (cumulative_args_t ca ATTRIBUTE_UNUSED,
- machine_mode mode ATTRIBUTE_UNUSED,
- const_tree type ATTRIBUTE_UNUSED, bool named)
+hook_callee_copies_named (cumulative_args_t, const function_arg_info &arg)
{
- return named;
+ return arg.named;
}
/* Emit to STREAM the assembler syntax for insn operand X. */
return get_identifier (stripped);
}
+/* The default implementation of TARGET_TRANSLATE_MODE_ATTRIBUTE. */
+
+machine_mode
+default_translate_mode_attribute (machine_mode mode)
+{
+ return mode;
+}
+
/* True if MODE is valid for the target. By "valid", we mean able to
be manipulated in non-trivial ways. In particular, this means all
the arithmetic is supported.
return opt_scalar_float_mode ();
}
+/* Define this to return true if the _Floatn and _Floatnx built-in functions
+ should implicitly enable the built-in function without the __builtin_ prefix
+ in addition to the normal built-in function with the __builtin_ prefix. The
+ default is to only enable built-in functions without the __builtin_ prefix
+ for the GNU C langauge. The argument FUNC is the enum builtin_in_function
+ id of the function to be enabled. */
+
+bool
+default_floatn_builtin_p (int func ATTRIBUTE_UNUSED)
+{
+ static bool first_time_p = true;
+ static bool c_or_objective_c;
+
+ if (first_time_p)
+ {
+ first_time_p = false;
+ c_or_objective_c = lang_GNU_C () || lang_GNU_OBJC ();
+ }
+
+ return c_or_objective_c;
+}
+
/* Make some target macros useable by target-independent code. */
bool
targhook_words_big_endian (void)
return HAVE_GNU_INDIRECT_FUNCTION;
}
+/* Return true if we predict the loop LOOP will be transformed to a
+ low-overhead loop, otherwise return false.
+
+ By default, false is returned, as this hook's applicability should be
+ verified for each target. Target maintainers should re-define the hook
+ if the target can take advantage of it. */
+
+bool
+default_predict_doloop_p (class loop *loop ATTRIBUTE_UNUSED)
+{
+ return false;
+}
+
/* NULL if INSN insn is valid within a low-overhead loop, otherwise returns
an error message.
return NULL_TREE;
}
-/* Vectorized conversion. */
-
-tree
-default_builtin_vectorized_conversion (unsigned int code ATTRIBUTE_UNUSED,
- tree dest_type ATTRIBUTE_UNUSED,
- tree src_type ATTRIBUTE_UNUSED)
-{
- return NULL_TREE;
-}
-
/* Default vectorizer cost model values. */
int
return 3;
case vec_construct:
- return TYPE_VECTOR_SUBPARTS (vectype) - 1;
+ return estimated_poly_value (TYPE_VECTOR_SUBPARTS (vectype)) - 1;
default:
gcc_unreachable ();
}
bool
-hook_bool_CUMULATIVE_ARGS_mode_tree_bool_false (
- cumulative_args_t ca ATTRIBUTE_UNUSED,
- machine_mode mode ATTRIBUTE_UNUSED,
- const_tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED)
+hook_bool_CUMULATIVE_ARGS_arg_info_false (cumulative_args_t,
+ const function_arg_info &)
{
return false;
}
bool
-hook_bool_CUMULATIVE_ARGS_mode_tree_bool_true (
- cumulative_args_t ca ATTRIBUTE_UNUSED,
- machine_mode mode ATTRIBUTE_UNUSED,
- const_tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED)
+hook_bool_CUMULATIVE_ARGS_arg_info_true (cumulative_args_t,
+ const function_arg_info &)
{
return true;
}
int
-hook_int_CUMULATIVE_ARGS_mode_tree_bool_0 (
- cumulative_args_t ca ATTRIBUTE_UNUSED,
- machine_mode mode ATTRIBUTE_UNUSED,
- tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED)
+hook_int_CUMULATIVE_ARGS_arg_info_0 (cumulative_args_t,
+ const function_arg_info &)
{
return 0;
}
void
-default_function_arg_advance (cumulative_args_t ca ATTRIBUTE_UNUSED,
- machine_mode mode ATTRIBUTE_UNUSED,
- const_tree type ATTRIBUTE_UNUSED,
- bool named ATTRIBUTE_UNUSED)
+hook_void_CUMULATIVE_ARGS_tree (cumulative_args_t ca ATTRIBUTE_UNUSED,
+ tree ATTRIBUTE_UNUSED)
+{
+}
+
+void
+default_function_arg_advance (cumulative_args_t, const function_arg_info &)
{
gcc_unreachable ();
}
size = int_size_in_bytes (type);
}
else
- size = GET_MODE_SIZE (mode);
+ /* Targets with variable-sized modes must override this hook
+ and handle variable-sized modes explicitly. */
+ size = GET_MODE_SIZE (mode).to_constant ();
if (size < (PARM_BOUNDARY / BITS_PER_UNIT))
return PAD_DOWNWARD;
}
rtx
-default_function_arg (cumulative_args_t ca ATTRIBUTE_UNUSED,
- machine_mode mode ATTRIBUTE_UNUSED,
- const_tree type ATTRIBUTE_UNUSED,
- bool named ATTRIBUTE_UNUSED)
+default_function_arg (cumulative_args_t, const function_arg_info &)
{
gcc_unreachable ();
}
rtx
-default_function_incoming_arg (cumulative_args_t ca ATTRIBUTE_UNUSED,
- machine_mode mode ATTRIBUTE_UNUSED,
- const_tree type ATTRIBUTE_UNUSED,
- bool named ATTRIBUTE_UNUSED)
+default_function_incoming_arg (cumulative_args_t, const function_arg_info &)
{
gcc_unreachable ();
}
const_rtx fun ATTRIBUTE_UNUSED)
{
#ifdef LIBCALL_VALUE
- return LIBCALL_VALUE (mode);
+ return LIBCALL_VALUE (MACRO_MODE (mode));
#else
gcc_unreachable ();
#endif
sorry ("nested function trampolines not supported on this target");
}
-int
-default_return_pops_args (tree fundecl ATTRIBUTE_UNUSED,
- tree funtype ATTRIBUTE_UNUSED,
- int size ATTRIBUTE_UNUSED)
+poly_int64
+default_return_pops_args (tree, tree, poly_int64)
{
return 0;
}
-reg_class_t
-default_branch_target_register_class (void)
-{
- return NO_REGS;
-}
-
reg_class_t
default_ira_change_pseudo_allocno_class (int regno ATTRIBUTE_UNUSED,
reg_class_t cl,
}
#ifdef SECONDARY_INPUT_RELOAD_CLASS
if (in_p)
- rclass = SECONDARY_INPUT_RELOAD_CLASS (reload_class, reload_mode, x);
+ rclass = SECONDARY_INPUT_RELOAD_CLASS (reload_class,
+ MACRO_MODE (reload_mode), x);
#endif
#ifdef SECONDARY_OUTPUT_RELOAD_CLASS
if (! in_p)
- rclass = SECONDARY_OUTPUT_RELOAD_CLASS (reload_class, reload_mode, x);
+ rclass = SECONDARY_OUTPUT_RELOAD_CLASS (reload_class,
+ MACRO_MODE (reload_mode), x);
#endif
if (rclass != NO_REGS)
{
default_secondary_memory_needed_mode (machine_mode mode)
{
if (!targetm.lra_p ()
- && GET_MODE_BITSIZE (mode) < BITS_PER_WORD
+ && known_lt (GET_MODE_BITSIZE (mode), BITS_PER_WORD)
&& INTEGRAL_MODE_P (mode))
return mode_for_size (BITS_PER_WORD, GET_MODE_CLASS (mode), 0).require ();
return mode;
return flag_pic ? 3 : 0;
}
+/* By default, address diff vectors are generated
+for jump tables when flag_pic is true. */
+
+bool
+default_generate_pic_addr_diff_vec (void)
+{
+ return flag_pic;
+}
+
/* By default, do no modification. */
tree default_mangle_decl_assembler_name (tree decl ATTRIBUTE_UNUSED,
tree id)
return id;
}
-/* Default to natural alignment for vector types. */
+/* The default implementation of TARGET_STATIC_RTX_ALIGNMENT. */
+
HOST_WIDE_INT
-default_vector_alignment (const_tree type)
+default_static_rtx_alignment (machine_mode mode)
+{
+ return GET_MODE_ALIGNMENT (mode);
+}
+
+/* The default implementation of TARGET_CONSTANT_ALIGNMENT. */
+
+HOST_WIDE_INT
+default_constant_alignment (const_tree, HOST_WIDE_INT align)
{
- HOST_WIDE_INT align = tree_to_shwi (TYPE_SIZE (type));
- if (align > MAX_OFILE_ALIGNMENT)
- align = MAX_OFILE_ALIGNMENT;
return align;
}
+/* An implementation of TARGET_CONSTANT_ALIGNMENT that aligns strings
+ to at least BITS_PER_WORD but otherwise makes no changes. */
+
+HOST_WIDE_INT
+constant_alignment_word_strings (const_tree exp, HOST_WIDE_INT align)
+{
+ if (TREE_CODE (exp) == STRING_CST)
+ return MAX (align, BITS_PER_WORD);
+ return align;
+}
+
+/* Default to natural alignment for vector types, bounded by
+ MAX_OFILE_ALIGNMENT. */
+
+HOST_WIDE_INT
+default_vector_alignment (const_tree type)
+{
+ unsigned HOST_WIDE_INT align = MAX_OFILE_ALIGNMENT;
+ tree size = TYPE_SIZE (type);
+ if (tree_fits_uhwi_p (size))
+ align = tree_to_uhwi (size);
+
+ return align < MAX_OFILE_ALIGNMENT ? align : MAX_OFILE_ALIGNMENT;
+}
+
/* The default implementation of
TARGET_VECTORIZE_PREFERRED_VECTOR_ALIGNMENT. */
-HOST_WIDE_INT
+poly_uint64
default_preferred_vector_alignment (const_tree type)
{
return TYPE_ALIGN (type);
return word_mode;
}
-/* By default only the size derived from the preferred vector mode
- is tried. */
+/* By default do not split reductions further. */
+
+machine_mode
+default_split_reduction (machine_mode mode)
+{
+ return mode;
+}
+
+/* By default only the preferred vector mode is tried. */
unsigned int
-default_autovectorize_vector_sizes (void)
+default_autovectorize_vector_modes (vector_modes *, bool)
{
return 0;
}
-/* By defaults a vector of integers is used as a mask. */
+/* The default implementation of TARGET_VECTORIZE_RELATED_MODE. */
opt_machine_mode
-default_get_mask_mode (unsigned nunits, unsigned vector_size)
-{
- unsigned elem_size = vector_size / nunits;
- scalar_int_mode elem_mode
- = smallest_int_mode_for_size (elem_size * BITS_PER_UNIT);
- machine_mode vector_mode;
+default_vectorize_related_mode (machine_mode vector_mode,
+ scalar_mode element_mode,
+ poly_uint64 nunits)
+{
+ machine_mode result_mode;
+ if ((maybe_ne (nunits, 0U)
+ || multiple_p (GET_MODE_SIZE (vector_mode),
+ GET_MODE_SIZE (element_mode), &nunits))
+ && mode_for_vector (element_mode, nunits).exists (&result_mode)
+ && VECTOR_MODE_P (result_mode)
+ && targetm.vector_mode_supported_p (result_mode))
+ return result_mode;
- gcc_assert (elem_size * nunits == vector_size);
+ return opt_machine_mode ();
+}
- if (mode_for_vector (elem_mode, nunits).exists (&vector_mode)
- && VECTOR_MODE_P (vector_mode)
- && targetm.vector_mode_supported_p (vector_mode))
- return vector_mode;
+/* By default a vector of integers is used as a mask. */
- return opt_machine_mode ();
+opt_machine_mode
+default_get_mask_mode (machine_mode mode)
+{
+ return related_int_vector_mode (mode);
+}
+
+/* By default consider masked stores to be expensive. */
+
+bool
+default_empty_mask_is_expensive (unsigned ifn)
+{
+ return ifn == IFN_MASK_STORE;
}
/* By default, the cost model accumulates three separate costs (prologue,
array of three unsigned ints, set it to zero, and return its address. */
void *
-default_init_cost (struct loop *loop_info ATTRIBUTE_UNUSED)
+default_init_cost (class loop *loop_info ATTRIBUTE_UNUSED)
{
unsigned *cost = XNEWVEC (unsigned, 3);
cost[vect_prologue] = cost[vect_body] = cost[vect_epilogue] = 0;
it into the cost specified by WHERE, and returns the cost added. */
unsigned
-default_add_stmt_cost (void *data, int count, enum vect_cost_for_stmt kind,
- struct _stmt_vec_info *stmt_info, int misalign,
+default_add_stmt_cost (class vec_info *vinfo, void *data, int count,
+ enum vect_cost_for_stmt kind,
+ class _stmt_vec_info *stmt_info, tree vectype,
+ int misalign,
enum vect_cost_model_location where)
{
unsigned *cost = (unsigned *) data;
unsigned retval = 0;
-
- tree vectype = stmt_info ? stmt_vectype (stmt_info) : NULL_TREE;
int stmt_cost = targetm.vectorize.builtin_vectorization_cost (kind, vectype,
misalign);
/* Statements in an inner loop relative to the loop being
vectorized are weighted more heavily. The value here is
arbitrary and could potentially be improved with analysis. */
- if (where == vect_body && stmt_info && stmt_in_inner_loop_p (stmt_info))
+ if (where == vect_body && stmt_info
+ && stmt_in_inner_loop_p (vinfo, stmt_info))
count *= 50; /* FIXME. */
retval = (unsigned) (count * stmt_cost);
if (TYPE_UNSIGNED (TREE_TYPE (base))
|| TYPE_MODE (TREE_TYPE (base)) != TYPE_MODE (integer_type_node))
return false;
- /* The default implementation assumes an errno location
- declaration is never defined in the current compilation unit. */
+ /* The default implementation assumes an errno location declaration
+ is never defined in the current compilation unit and may not be
+ aliased by a local variable. */
if (DECL_P (base)
+ && DECL_EXTERNAL (base)
&& !TREE_STATIC (base))
return true;
else if (TREE_CODE (base) == MEM_REF
unsigned int
default_hard_regno_nregs (unsigned int, machine_mode mode)
{
- return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD);
+ /* Targets with variable-sized modes must provide their own definition
+ of this hook. */
+ return CEIL (GET_MODE_SIZE (mode).to_constant (), UNITS_PER_WORD);
}
bool
return false;
}
+extern bool default_new_address_profitable_p (rtx, rtx);
+
+
+/* The default implementation of TARGET_NEW_ADDRESS_PROFITABLE_P. */
+
+bool
+default_new_address_profitable_p (rtx memref ATTRIBUTE_UNUSED,
+ rtx_insn *insn ATTRIBUTE_UNUSED,
+ rtx new_addr ATTRIBUTE_UNUSED)
+{
+ return true;
+}
+
bool
default_target_option_valid_attribute_p (tree ARG_UNUSED (fndecl),
tree ARG_UNUSED (name),
do not have the "target" pragma. */
if (args)
warning (OPT_Wpragmas,
- "#pragma GCC target is not supported for this machine");
+ "%<#pragma GCC target%> is not supported for this machine");
return false;
}
return false;
}
+/* By default assume that libc has not a fast implementation. */
+
+bool
+default_libc_has_fast_function (int fcode ATTRIBUTE_UNUSED)
+{
+ return false;
+}
+
bool
gnu_libc_has_function (enum function_class fn_class ATTRIBUTE_UNUSED)
{
#ifndef MEMORY_MOVE_COST
return (4 + memory_move_secondary_cost (mode, (enum reg_class) rclass, in));
#else
- return MEMORY_MOVE_COST (mode, (enum reg_class) rclass, in);
+ return MEMORY_MOVE_COST (MACRO_MODE (mode), (enum reg_class) rclass, in);
#endif
}
#ifndef REGISTER_MOVE_COST
return 2;
#else
- return REGISTER_MOVE_COST (mode, (enum reg_class) from, (enum reg_class) to);
+ return REGISTER_MOVE_COST (MACRO_MODE (mode),
+ (enum reg_class) from, (enum reg_class) to);
#endif
}
return STRICT_ALIGNMENT;
}
+/* The default implementation of TARGET_ESTIMATED_POLY_VALUE. */
+
+HOST_WIDE_INT
+default_estimated_poly_value (poly_int64 x)
+{
+ return x.coeffs[0];
+}
+
/* For hooks which use the MOVE_RATIO macro, this gives the legacy default
behavior. SPEED_P is true if we are compiling for speed. */
#ifdef MOVE_RATIO
move_ratio = (unsigned int) MOVE_RATIO (speed_p);
#else
-#if defined (HAVE_movmemqi) || defined (HAVE_movmemhi) || defined (HAVE_movmemsi) || defined (HAVE_movmemdi) || defined (HAVE_movmemti)
+#if defined (HAVE_cpymemqi) || defined (HAVE_cpymemhi) || defined (HAVE_cpymemsi) || defined (HAVE_cpymemdi) || defined (HAVE_cpymemti)
move_ratio = 2;
-#else /* No movmem patterns, pick a default. */
+#else /* No cpymem patterns, pick a default. */
move_ratio = ((speed_p) ? 15 : 3);
#endif
#endif
}
/* Return TRUE if the move_by_pieces/set_by_pieces infrastructure should be
- used; return FALSE if the movmem/setmem optab should be expanded, or
+ used; return FALSE if the cpymem/setmem optab should be expanded, or
a call to memcpy emitted. */
bool
char buf[256];
static int patch_area_number;
section *previous_section = in_section;
+ const char *asm_op = integer_asm_op (POINTER_SIZE_UNITS, false);
+ gcc_assert (asm_op != NULL);
patch_area_number++;
ASM_GENERATE_INTERNAL_LABEL (buf, "LPFE", patch_area_number);
switch_to_section (get_section ("__patchable_function_entries",
- 0, NULL));
- fputs (integer_asm_op (POINTER_SIZE_UNITS, false), file);
+ SECTION_WRITE | SECTION_RELRO, NULL));
+ assemble_align (POINTER_SIZE);
+ fputs (asm_op, file);
assemble_name_raw (file, buf);
fputc ('\n', file);
unsigned i;
for (i = 0; i < patch_area_size; ++i)
- fprintf (file, "\t%s\n", nop_templ);
+ output_asm_insn (nop_templ, NULL);
}
bool
machine_mode mode ATTRIBUTE_UNUSED)
{
#ifdef CLASS_MAX_NREGS
- return (unsigned char) CLASS_MAX_NREGS ((enum reg_class) rclass, mode);
+ return (unsigned char) CLASS_MAX_NREGS ((enum reg_class) rclass,
+ MACRO_MODE (mode));
#else
- return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
+ /* Targets with variable-sized modes must provide their own definition
+ of this hook. */
+ unsigned int size = GET_MODE_SIZE (mode).to_constant ();
+ return (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
#endif
}
return UI_NONE;
}
+/* Targets that set NUM_POLY_INT_COEFFS to something greater than 1
+ must define this hook. */
+
+unsigned int
+default_dwarf_poly_indeterminate_value (unsigned int, unsigned int *, int *)
+{
+ gcc_unreachable ();
+}
+
/* Determine the correct mode for a Dwarf frame register that represents
register REGNO. */
{
machine_mode save_mode = reg_raw_mode[regno];
- if (targetm.hard_regno_call_part_clobbered (regno, save_mode))
- save_mode = choose_hard_reg_mode (regno, 1, true);
+ if (targetm.hard_regno_call_part_clobbered (eh_edge_abi.id (),
+ regno, save_mode))
+ save_mode = choose_hard_reg_mode (regno, 1, &eh_edge_abi);
return save_mode;
}
/* To be used by targets where reg_raw_mode doesn't return the right
mode for registers used in apply_builtin_return and apply_builtin_arg. */
-machine_mode
+fixed_size_mode
default_get_reg_raw_mode (int regno)
{
- return reg_raw_mode[regno];
+ /* Targets must override this hook if the underlying register is
+ variable-sized. */
+ return as_a <fixed_size_mode> (reg_raw_mode[regno]);
}
/* Return true if a leaf function should stay leaf even with profiling
/* -fpic and -fpie also usually make a PCH invalid. */
if (data[0] != flag_pic)
- return _("created and used with different settings of -fpic");
+ return _("created and used with different settings of %<-fpic%>");
if (data[1] != flag_pie)
- return _("created and used with different settings of -fpie");
+ return _("created and used with different settings of %<-fpie%>");
data += 2;
/* Check target_flags. */
if (ARGS_GROW_DOWNWARD)
gcc_unreachable ();
- indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
+ indirect = pass_va_arg_by_reference (type);
if (indirect)
type = build_pointer_type (type);
+ if (targetm.calls.split_complex_arg
+ && TREE_CODE (type) == COMPLEX_TYPE
+ && targetm.calls.split_complex_arg (type))
+ {
+ tree real_part, imag_part;
+
+ real_part = std_gimplify_va_arg_expr (valist,
+ TREE_TYPE (type), pre_p, NULL);
+ real_part = get_initialized_tmp_var (real_part, pre_p);
+
+ imag_part = std_gimplify_va_arg_expr (unshare_expr (valist),
+ TREE_TYPE (type), pre_p, NULL);
+ imag_part = get_initialized_tmp_var (imag_part, pre_p);
+
+ return build2 (COMPLEX_EXPR, type, real_part, imag_part);
+ }
+
align = PARM_BOUNDARY / BITS_PER_UNIT;
boundary = targetm.calls.function_arg_boundary (TYPE_MODE (type), type);
boundary /= BITS_PER_UNIT;
/* Hoist the valist value into a temporary for the moment. */
- valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
+ valist_tmp = get_initialized_tmp_var (valist, pre_p);
/* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
requires greater alignment, we must perform dynamic alignment. */
if (boundary > align
+ && !TYPE_EMPTY_P (type)
&& !integer_zerop (TYPE_SIZE (type)))
{
t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
}
/* Compute the rounded size of the type. */
- type_size = size_in_bytes (type);
+ type_size = arg_size_in_bytes (type);
rounded_size = round_up (type_size, align);
/* Reduce rounded_size so it's sharable with the postqueue. */
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;
- TYPE_NAME (res) = get_identifier ("__bounds_type");
- SET_TYPE_MODE (res, targetm.chkp_bound_mode ());
- layout_type (res);
- return res;
-}
-
-machine_mode
-default_chkp_bound_mode (void)
-{
- return VOIDmode;
-}
-
-tree
-default_builtin_chkp_function (unsigned int fcode ATTRIBUTE_UNUSED)
-{
- return NULL_TREE;
-}
-
-rtx
-default_chkp_function_value_bounds (const_tree ret_type ATTRIBUTE_UNUSED,
- const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
- bool outgoing ATTRIBUTE_UNUSED)
-{
- gcc_unreachable ();
-}
-
-tree
-default_chkp_make_bounds_constant (HOST_WIDE_INT lb ATTRIBUTE_UNUSED,
- HOST_WIDE_INT ub ATTRIBUTE_UNUSED)
-{
- return NULL_TREE;
-}
-
-int
-default_chkp_initialize_bounds (tree var ATTRIBUTE_UNUSED,
- tree lb ATTRIBUTE_UNUSED,
- tree ub ATTRIBUTE_UNUSED,
- tree *stmts ATTRIBUTE_UNUSED)
-{
- return 0;
-}
-
-void
-default_setup_incoming_vararg_bounds (cumulative_args_t ca ATTRIBUTE_UNUSED,
- machine_mode mode ATTRIBUTE_UNUSED,
- tree type ATTRIBUTE_UNUSED,
- int *pretend_arg_size ATTRIBUTE_UNUSED,
- int second_time ATTRIBUTE_UNUSED)
-{
-}
-
/* An implementation of TARGET_CAN_USE_DOLOOP_P for targets that do
not support nested low-overhead loops. */
{
bool predictable_p = predictable_edge_p (e);
- enum compiler_param param
- = (predictable_p
- ? PARAM_MAX_RTL_IF_CONVERSION_PREDICTABLE_COST
- : PARAM_MAX_RTL_IF_CONVERSION_UNPREDICTABLE_COST);
-
- /* If we have a parameter set, use that, otherwise take a guess using
- BRANCH_COST. */
- if (global_options_set.x_param_values[param])
- return PARAM_VALUE (param);
+ if (predictable_p)
+ {
+ if (global_options_set.x_param_max_rtl_if_conversion_predictable_cost)
+ return param_max_rtl_if_conversion_predictable_cost;
+ }
else
- return BRANCH_COST (true, predictable_p) * COSTS_N_INSNS (3);
+ {
+ if (global_options_set.x_param_max_rtl_if_conversion_unpredictable_cost)
+ return param_max_rtl_if_conversion_unpredictable_cost;
+ }
+
+ return BRANCH_COST (true, predictable_p) * COSTS_N_INSNS (3);
}
/* Default implementation of TARGET_MIN_ARITHMETIC_PRECISION. */
return FLT_EVAL_METHOD_PROMOTE_TO_FLOAT;
}
+/* Default implementation for
+ TARGET_STACK_CLASH_PROTECTION_ALLOCA_PROBE_RANGE. */
HOST_WIDE_INT
-default_stack_clash_protection_final_dynamic_probe (rtx residual ATTRIBUTE_UNUSED)
+default_stack_clash_protection_alloca_probe_range (void)
{
return 0;
}
+/* The default implementation of TARGET_EARLY_REMAT_MODES. */
+
+void
+default_select_early_remat_modes (sbitmap)
+{
+}
+
+/* The default implementation of TARGET_PREFERRED_ELSE_VALUE. */
+
+tree
+default_preferred_else_value (unsigned, tree type, unsigned, tree *)
+{
+ return build_zero_cst (type);
+}
+
+/* Default implementation of TARGET_HAVE_SPECULATION_SAFE_VALUE. */
+bool
+default_have_speculation_safe_value (bool active ATTRIBUTE_UNUSED)
+{
+#ifdef HAVE_speculation_barrier
+ return active ? HAVE_speculation_barrier : true;
+#else
+ return false;
+#endif
+}
+/* Alternative implementation of TARGET_HAVE_SPECULATION_SAFE_VALUE
+ that can be used on targets that never have speculative execution. */
+bool
+speculation_safe_value_not_needed (bool active)
+{
+ return !active;
+}
+
+/* Default implementation of the speculation-safe-load builtin. This
+ implementation simply copies val to result and generates a
+ speculation_barrier insn, if such a pattern is defined. */
+rtx
+default_speculation_safe_value (machine_mode mode ATTRIBUTE_UNUSED,
+ rtx result, rtx val,
+ rtx failval ATTRIBUTE_UNUSED)
+{
+ emit_move_insn (result, val);
+
+#ifdef HAVE_speculation_barrier
+ /* Assume the target knows what it is doing: if it defines a
+ speculation barrier, but it is not enabled, then assume that one
+ isn't needed. */
+ if (HAVE_speculation_barrier)
+ emit_insn (gen_speculation_barrier ());
+#endif
+
+ return result;
+}
+
#include "gt-targhooks.h"