This patch uses opt_scalar_mode when iterating over scalar modes.
2017-08-30 Richard Sandiford <richard.sandiford@linaro.org>
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>
gcc/
* coretypes.h (opt_scalar_mode): New typedef.
* gdbhooks.py (build_pretty_printers): Handle it.
* machmode.h (mode_iterator::get_2xwider): Add overload for
opt_mode<T>.
* emit-rtl.c (init_emit_once): Use opt_scalar_mode when iterating
over scalar modes.
* expr.c (convert_mode_scalar): Likewise.
* omp-low.c (omp_clause_aligned_alignment): Likewise.
* optabs.c (expand_float): Likewise.
(expand_fix): Likewise.
* tree-vect-stmts.c (vectorizable_conversion): Likewise.
gcc/c-family/
* c-common.c (c_common_fixed_point_type_for_size): Use opt_scalar_mode
for the mode iterator.
Co-Authored-By: Alan Hayward <alan.hayward@arm.com>
Co-Authored-By: David Sherwood <david.sherwood@arm.com>
From-SVN: r251522
+2017-08-30 Richard Sandiford <richard.sandiford@linaro.org>
+ Alan Hayward <alan.hayward@arm.com>
+ David Sherwood <david.sherwood@arm.com>
+
+ * coretypes.h (opt_scalar_mode): New typedef.
+ * gdbhooks.py (build_pretty_printers): Handle it.
+ * machmode.h (mode_iterator::get_2xwider): Add overload for
+ opt_mode<T>.
+ * emit-rtl.c (init_emit_once): Use opt_scalar_mode when iterating
+ over scalar modes.
+ * expr.c (convert_mode_scalar): Likewise.
+ * omp-low.c (omp_clause_aligned_alignment): Likewise.
+ * optabs.c (expand_float): Likewise.
+ (expand_fix): Likewise.
+ * tree-vect-stmts.c (vectorizable_conversion): Likewise.
+
2017-08-30 Richard Sandiford <richard.sandiford@linaro.org>
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>
+2017-08-30 Richard Sandiford <richard.sandiford@linaro.org>
+ Alan Hayward <alan.hayward@arm.com>
+ David Sherwood <david.sherwood@arm.com>
+
+ * c-common.c (c_common_fixed_point_type_for_size): Use opt_scalar_mode
+ for the mode iterator.
+
2017-08-30 Richard Sandiford <richard.sandiford@linaro.org>
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>
else
mclass = unsignedp ? MODE_UACCUM : MODE_ACCUM;
- machine_mode mode;
- FOR_EACH_MODE_IN_CLASS (mode, mclass)
- if (GET_MODE_IBIT (mode) >= ibit && GET_MODE_FBIT (mode) >= fbit)
- break;
+ opt_scalar_mode opt_mode;
+ scalar_mode mode;
+ FOR_EACH_MODE_IN_CLASS (opt_mode, mclass)
+ {
+ mode = opt_mode.require ();
+ if (GET_MODE_IBIT (mode) >= ibit && GET_MODE_FBIT (mode) >= fbit)
+ break;
+ }
- if (mode == VOIDmode || !targetm.scalar_mode_supported_p (mode))
+ if (!opt_mode.exists (&mode) || !targetm.scalar_mode_supported_p (mode))
{
sorry ("GCC cannot support operators with integer types and "
"fixed-point types that have too many integral and "
class scalar_int_mode;
class scalar_float_mode;
template<typename> class opt_mode;
+typedef opt_mode<scalar_mode> opt_scalar_mode;
typedef opt_mode<scalar_int_mode> opt_scalar_int_mode;
typedef opt_mode<scalar_float_mode> opt_scalar_float_mode;
template<typename> class pod_mode;
int i;
machine_mode mode;
scalar_float_mode double_mode;
+ opt_scalar_mode smode_iter;
/* Initialize the CONST_INT, CONST_WIDE_INT, CONST_DOUBLE,
CONST_FIXED, and memory attribute hash tables. */
const_tiny_rtx[1][(int) mode] = gen_const_vector (mode, 1);
}
- FOR_EACH_MODE_IN_CLASS (mode, MODE_FRACT)
+ FOR_EACH_MODE_IN_CLASS (smode_iter, MODE_FRACT)
{
- FCONST0 (mode).data.high = 0;
- FCONST0 (mode).data.low = 0;
- FCONST0 (mode).mode = mode;
- const_tiny_rtx[0][(int) mode] = CONST_FIXED_FROM_FIXED_VALUE (
- FCONST0 (mode), mode);
+ scalar_mode smode = smode_iter.require ();
+ FCONST0 (smode).data.high = 0;
+ FCONST0 (smode).data.low = 0;
+ FCONST0 (smode).mode = smode;
+ const_tiny_rtx[0][(int) smode]
+ = CONST_FIXED_FROM_FIXED_VALUE (FCONST0 (smode), smode);
}
- FOR_EACH_MODE_IN_CLASS (mode, MODE_UFRACT)
+ FOR_EACH_MODE_IN_CLASS (smode_iter, MODE_UFRACT)
{
- FCONST0 (mode).data.high = 0;
- FCONST0 (mode).data.low = 0;
- FCONST0 (mode).mode = mode;
- const_tiny_rtx[0][(int) mode] = CONST_FIXED_FROM_FIXED_VALUE (
- FCONST0 (mode), mode);
+ scalar_mode smode = smode_iter.require ();
+ FCONST0 (smode).data.high = 0;
+ FCONST0 (smode).data.low = 0;
+ FCONST0 (smode).mode = smode;
+ const_tiny_rtx[0][(int) smode]
+ = CONST_FIXED_FROM_FIXED_VALUE (FCONST0 (smode), smode);
}
- FOR_EACH_MODE_IN_CLASS (mode, MODE_ACCUM)
+ FOR_EACH_MODE_IN_CLASS (smode_iter, MODE_ACCUM)
{
- FCONST0 (mode).data.high = 0;
- FCONST0 (mode).data.low = 0;
- FCONST0 (mode).mode = mode;
- const_tiny_rtx[0][(int) mode] = CONST_FIXED_FROM_FIXED_VALUE (
- FCONST0 (mode), mode);
+ scalar_mode smode = smode_iter.require ();
+ FCONST0 (smode).data.high = 0;
+ FCONST0 (smode).data.low = 0;
+ FCONST0 (smode).mode = smode;
+ const_tiny_rtx[0][(int) smode]
+ = CONST_FIXED_FROM_FIXED_VALUE (FCONST0 (smode), smode);
/* We store the value 1. */
- FCONST1 (mode).data.high = 0;
- FCONST1 (mode).data.low = 0;
- FCONST1 (mode).mode = mode;
- FCONST1 (mode).data
- = double_int_one.lshift (GET_MODE_FBIT (mode),
+ FCONST1 (smode).data.high = 0;
+ FCONST1 (smode).data.low = 0;
+ FCONST1 (smode).mode = smode;
+ FCONST1 (smode).data
+ = double_int_one.lshift (GET_MODE_FBIT (smode),
HOST_BITS_PER_DOUBLE_INT,
- SIGNED_FIXED_POINT_MODE_P (mode));
- const_tiny_rtx[1][(int) mode] = CONST_FIXED_FROM_FIXED_VALUE (
- FCONST1 (mode), mode);
+ SIGNED_FIXED_POINT_MODE_P (smode));
+ const_tiny_rtx[1][(int) smode]
+ = CONST_FIXED_FROM_FIXED_VALUE (FCONST1 (smode), smode);
}
- FOR_EACH_MODE_IN_CLASS (mode, MODE_UACCUM)
+ FOR_EACH_MODE_IN_CLASS (smode_iter, MODE_UACCUM)
{
- FCONST0 (mode).data.high = 0;
- FCONST0 (mode).data.low = 0;
- FCONST0 (mode).mode = mode;
- const_tiny_rtx[0][(int) mode] = CONST_FIXED_FROM_FIXED_VALUE (
- FCONST0 (mode), mode);
+ scalar_mode smode = smode_iter.require ();
+ FCONST0 (smode).data.high = 0;
+ FCONST0 (smode).data.low = 0;
+ FCONST0 (smode).mode = smode;
+ const_tiny_rtx[0][(int) smode]
+ = CONST_FIXED_FROM_FIXED_VALUE (FCONST0 (smode), smode);
/* We store the value 1. */
- FCONST1 (mode).data.high = 0;
- FCONST1 (mode).data.low = 0;
- FCONST1 (mode).mode = mode;
- FCONST1 (mode).data
- = double_int_one.lshift (GET_MODE_FBIT (mode),
+ FCONST1 (smode).data.high = 0;
+ FCONST1 (smode).data.low = 0;
+ FCONST1 (smode).mode = smode;
+ FCONST1 (smode).data
+ = double_int_one.lshift (GET_MODE_FBIT (smode),
HOST_BITS_PER_DOUBLE_INT,
- SIGNED_FIXED_POINT_MODE_P (mode));
- const_tiny_rtx[1][(int) mode] = CONST_FIXED_FROM_FIXED_VALUE (
- FCONST1 (mode), mode);
+ SIGNED_FIXED_POINT_MODE_P (smode));
+ const_tiny_rtx[1][(int) smode]
+ = CONST_FIXED_FROM_FIXED_VALUE (FCONST1 (smode), smode);
}
FOR_EACH_MODE_IN_CLASS (mode, MODE_VECTOR_FRACT)
if (STORE_FLAG_VALUE == 1)
const_tiny_rtx[1][(int) BImode] = const1_rtx;
- FOR_EACH_MODE_IN_CLASS (mode, MODE_POINTER_BOUNDS)
+ FOR_EACH_MODE_IN_CLASS (smode_iter, MODE_POINTER_BOUNDS)
{
- wide_int wi_zero = wi::zero (GET_MODE_PRECISION (mode));
- const_tiny_rtx[0][mode] = immed_wide_int_const (wi_zero, mode);
+ scalar_mode smode = smode_iter.require ();
+ wide_int wi_zero = wi::zero (GET_MODE_PRECISION (smode));
+ const_tiny_rtx[0][smode] = immed_wide_int_const (wi_zero, smode);
}
pc_rtx = gen_rtx_fmt_ (PC, VOIDmode);
}
else
{
- machine_mode intermediate;
+ scalar_mode intermediate;
rtx tmp;
int shift_amount;
/* Search for a mode to convert via. */
- FOR_EACH_MODE_FROM (intermediate, from_mode)
- if (((can_extend_p (to_mode, intermediate, unsignedp)
- != CODE_FOR_nothing)
- || (GET_MODE_SIZE (to_mode) < GET_MODE_SIZE (intermediate)
- && TRULY_NOOP_TRUNCATION_MODES_P (to_mode, intermediate)))
- && (can_extend_p (intermediate, from_mode, unsignedp)
- != CODE_FOR_nothing))
- {
- convert_move (to, convert_to_mode (intermediate, from,
- unsignedp), unsignedp);
- return;
- }
+ opt_scalar_mode intermediate_iter;
+ FOR_EACH_MODE_FROM (intermediate_iter, from_mode)
+ {
+ scalar_mode intermediate = intermediate_iter.require ();
+ if (((can_extend_p (to_mode, intermediate, unsignedp)
+ != CODE_FOR_nothing)
+ || (GET_MODE_SIZE (to_mode) < GET_MODE_SIZE (intermediate)
+ && TRULY_NOOP_TRUNCATION_MODES_P (to_mode,
+ intermediate)))
+ && (can_extend_p (intermediate, from_mode, unsignedp)
+ != CODE_FOR_nothing))
+ {
+ convert_move (to, convert_to_mode (intermediate, from,
+ unsignedp), unsignedp);
+ return;
+ }
+ }
/* No suitable intermediate mode.
Generate what we need with shifts. */
pp.add_printer_for_regex(r'opt_mode<(\S+)>',
'opt_mode', OptMachineModePrinter)
pp.add_printer_for_types(['opt_scalar_int_mode',
- 'opt_scalar_float_mode'],
+ 'opt_scalar_float_mode',
+ 'opt_scalar_mode'],
'opt_mode', OptMachineModePrinter)
pp.add_printer_for_regex(r'pod_mode<(\S+)>',
'pod_mode', MachineModePrinter)
/* Set mode iterator *ITER to the mode that is two times wider than the
current one, if such a mode exists. */
+ template<typename T>
+ inline void
+ get_2xwider (opt_mode<T> *iter)
+ {
+ *iter = GET_MODE_2XWIDER_MODE (iter->require ());
+ }
+
inline void
get_2xwider (machine_mode *iter)
{
/* Otherwise return implementation defined alignment. */
unsigned int al = 1;
- machine_mode mode, vmode;
+ opt_scalar_mode mode_iter;
int vs = targetm.vectorize.autovectorize_vector_sizes ();
if (vs)
vs = 1 << floor_log2 (vs);
static enum mode_class classes[]
= { MODE_INT, MODE_VECTOR_INT, MODE_FLOAT, MODE_VECTOR_FLOAT };
for (int i = 0; i < 4; i += 2)
- FOR_EACH_MODE_IN_CLASS (mode, classes[i])
+ /* The for loop above dictates that we only walk through scalar classes. */
+ FOR_EACH_MODE_IN_CLASS (mode_iter, classes[i])
{
- vmode = targetm.vectorize.preferred_simd_mode (mode);
+ scalar_mode mode = mode_iter.require ();
+ machine_mode vmode = targetm.vectorize.preferred_simd_mode (mode);
if (GET_MODE_CLASS (vmode) != classes[i + 1])
continue;
while (vs
&& is_a <scalar_mode> (GET_MODE (to), &to_mode)
&& is_a <scalar_mode> (GET_MODE (from), &from_mode))
{
+ opt_scalar_mode fmode_iter;
rtx_code_label *label = gen_label_rtx ();
rtx temp;
REAL_VALUE_TYPE offset;
least as wide as the target. Using FMODE will avoid rounding woes
with unsigned values greater than the signed maximum value. */
- FOR_EACH_MODE_FROM (fmode, to_mode)
- if (GET_MODE_PRECISION (from_mode) < GET_MODE_BITSIZE (fmode)
- && can_float_p (fmode, from_mode, 0) != CODE_FOR_nothing)
- break;
+ FOR_EACH_MODE_FROM (fmode_iter, to_mode)
+ {
+ scalar_mode fmode = fmode_iter.require ();
+ if (GET_MODE_PRECISION (from_mode) < GET_MODE_BITSIZE (fmode)
+ && can_float_p (fmode, from_mode, 0) != CODE_FOR_nothing)
+ break;
+ }
- if (fmode == VOIDmode)
+ if (!fmode_iter.exists (&fmode))
{
/* There is no such mode. Pretend the target is wide enough. */
fmode = to_mode;
enum insn_code icode;
rtx target = to;
machine_mode fmode, imode;
+ opt_scalar_mode fmode_iter;
bool must_trunc = false;
/* We first try to find a pair of modes, one real and one integer, at
if (unsignedp
&& is_a <scalar_int_mode> (GET_MODE (to), &to_mode)
&& HWI_COMPUTABLE_MODE_P (to_mode))
- FOR_EACH_MODE_FROM (fmode, GET_MODE (from))
- if (CODE_FOR_nothing != can_fix_p (to_mode, fmode, 0, &must_trunc)
- && (!DECIMAL_FLOAT_MODE_P (fmode)
- || GET_MODE_BITSIZE (fmode) > GET_MODE_PRECISION (to_mode)))
- {
- int bitsize;
- REAL_VALUE_TYPE offset;
- rtx limit;
- rtx_code_label *lab1, *lab2;
- rtx_insn *insn;
-
- bitsize = GET_MODE_PRECISION (to_mode);
- real_2expN (&offset, bitsize - 1, fmode);
- limit = const_double_from_real_value (offset, fmode);
- lab1 = gen_label_rtx ();
- lab2 = gen_label_rtx ();
-
- if (fmode != GET_MODE (from))
- from = convert_to_mode (fmode, from, 0);
-
- /* See if we need to do the subtraction. */
- do_pending_stack_adjust ();
- emit_cmp_and_jump_insns (from, limit, GE, NULL_RTX, GET_MODE (from),
- 0, lab1);
-
- /* If not, do the signed "fix" and branch around fixup code. */
- expand_fix (to, from, 0);
- emit_jump_insn (targetm.gen_jump (lab2));
- emit_barrier ();
-
- /* Otherwise, subtract 2**(N-1), convert to signed number,
- then add 2**(N-1). Do the addition using XOR since this
- will often generate better code. */
- emit_label (lab1);
- target = expand_binop (GET_MODE (from), sub_optab, from, limit,
- NULL_RTX, 0, OPTAB_LIB_WIDEN);
- expand_fix (to, target, 0);
- target = expand_binop (to_mode, xor_optab, to,
- gen_int_mode
- (HOST_WIDE_INT_1 << (bitsize - 1),
- to_mode),
- to, 1, OPTAB_LIB_WIDEN);
-
- if (target != to)
- emit_move_insn (to, target);
-
- emit_label (lab2);
-
- if (optab_handler (mov_optab, to_mode) != CODE_FOR_nothing)
- {
- /* Make a place for a REG_NOTE and add it. */
- insn = emit_move_insn (to, to);
- set_dst_reg_note (insn, REG_EQUAL,
- gen_rtx_fmt_e (UNSIGNED_FIX, to_mode,
- copy_rtx (from)),
- to);
- }
+ FOR_EACH_MODE_FROM (fmode_iter, as_a <scalar_mode> (GET_MODE (from)))
+ {
+ scalar_mode fmode = fmode_iter.require ();
+ if (CODE_FOR_nothing != can_fix_p (to_mode, fmode,
+ 0, &must_trunc)
+ && (!DECIMAL_FLOAT_MODE_P (fmode)
+ || (GET_MODE_BITSIZE (fmode) > GET_MODE_PRECISION (to_mode))))
+ {
+ int bitsize;
+ REAL_VALUE_TYPE offset;
+ rtx limit;
+ rtx_code_label *lab1, *lab2;
+ rtx_insn *insn;
+
+ bitsize = GET_MODE_PRECISION (to_mode);
+ real_2expN (&offset, bitsize - 1, fmode);
+ limit = const_double_from_real_value (offset, fmode);
+ lab1 = gen_label_rtx ();
+ lab2 = gen_label_rtx ();
- return;
- }
+ if (fmode != GET_MODE (from))
+ from = convert_to_mode (fmode, from, 0);
+
+ /* See if we need to do the subtraction. */
+ do_pending_stack_adjust ();
+ emit_cmp_and_jump_insns (from, limit, GE, NULL_RTX,
+ GET_MODE (from), 0, lab1);
+
+ /* If not, do the signed "fix" and branch around fixup code. */
+ expand_fix (to, from, 0);
+ emit_jump_insn (targetm.gen_jump (lab2));
+ emit_barrier ();
+
+ /* Otherwise, subtract 2**(N-1), convert to signed number,
+ then add 2**(N-1). Do the addition using XOR since this
+ will often generate better code. */
+ emit_label (lab1);
+ target = expand_binop (GET_MODE (from), sub_optab, from, limit,
+ NULL_RTX, 0, OPTAB_LIB_WIDEN);
+ expand_fix (to, target, 0);
+ target = expand_binop (to_mode, xor_optab, to,
+ gen_int_mode
+ (HOST_WIDE_INT_1 << (bitsize - 1),
+ to_mode),
+ to, 1, OPTAB_LIB_WIDEN);
+
+ if (target != to)
+ emit_move_insn (to, target);
+
+ emit_label (lab2);
+
+ if (optab_handler (mov_optab, to_mode) != CODE_FOR_nothing)
+ {
+ /* Make a place for a REG_NOTE and add it. */
+ insn = emit_move_insn (to, to);
+ set_dst_reg_note (insn, REG_EQUAL,
+ gen_rtx_fmt_e (UNSIGNED_FIX, to_mode,
+ copy_rtx (from)),
+ to);
+ }
+
+ return;
+ }
+ }
/* We can't do it with an insn, so use a library call. But first ensure
that the mode of TO is at least as wide as SImode, since those are the
needs to be generated. */
gcc_assert (ncopies >= 1);
- machine_mode lhs_mode = SCALAR_TYPE_MODE (lhs_type);
- machine_mode rhs_mode = SCALAR_TYPE_MODE (rhs_type);
+ bool found_mode = false;
+ scalar_mode lhs_mode = SCALAR_TYPE_MODE (lhs_type);
+ scalar_mode rhs_mode = SCALAR_TYPE_MODE (rhs_type);
+ opt_scalar_mode rhs_mode_iter;
/* Supportable by target? */
switch (modifier)
goto unsupported;
fltsz = GET_MODE_SIZE (lhs_mode);
- FOR_EACH_2XWIDER_MODE (rhs_mode, rhs_mode)
+ FOR_EACH_2XWIDER_MODE (rhs_mode_iter, rhs_mode)
{
+ rhs_mode = rhs_mode_iter.require ();
if (GET_MODE_SIZE (rhs_mode) > fltsz)
break;
if (supportable_widening_operation (NOP_EXPR, stmt, cvt_type,
vectype_in, &code1, &code2,
&multi_step_cvt, &interm_types))
- break;
+ {
+ found_mode = true;
+ break;
+ }
}
- if (rhs_mode == VOIDmode || GET_MODE_SIZE (rhs_mode) > fltsz)
+ if (!found_mode)
goto unsupported;
if (GET_MODE_SIZE (rhs_mode) == fltsz)