This patch uses opt_scalar_mode when iterating over scalar modes. 2017-07-13 Richard Sandiford <richard.sandif...@linaro.org> Alan Hayward <alan.hayw...@arm.com> David Sherwood <david.sherw...@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. Index: gcc/coretypes.h =================================================================== --- gcc/coretypes.h 2017-07-13 09:18:53.271650545 +0100 +++ gcc/coretypes.h 2017-07-13 09:18:56.810392248 +0100 @@ -59,6 +59,7 @@ typedef const struct rtx_def *const_rtx; 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; Index: gcc/gdbhooks.py =================================================================== --- gcc/gdbhooks.py 2017-07-13 09:18:53.273650396 +0100 +++ gcc/gdbhooks.py 2017-07-13 09:18:56.812392104 +0100 @@ -543,7 +543,8 @@ def build_pretty_printer(): 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) Index: gcc/machmode.h =================================================================== --- gcc/machmode.h 2017-07-13 09:18:53.274650323 +0100 +++ gcc/machmode.h 2017-07-13 09:18:56.812392104 +0100 @@ -836,6 +836,13 @@ is_float_mode (machine_mode mode, T *flo /* 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); + } + inline void get_2xwider (machine_mode *iter) { Index: gcc/emit-rtl.c =================================================================== --- gcc/emit-rtl.c 2017-07-13 09:18:54.682546579 +0100 +++ gcc/emit-rtl.c 2017-07-13 09:18:56.811392176 +0100 @@ -5891,6 +5891,7 @@ init_emit_once (void) 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. */ @@ -6005,62 +6006,66 @@ init_emit_once (void) 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); - } - - FOR_EACH_MODE_IN_CLASS (mode, 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); - } - - FOR_EACH_MODE_IN_CLASS (mode, 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; + 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 (smode_iter, MODE_UFRACT) + { + scalar_mode smode = *smode_iter; + 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 (smode_iter, MODE_ACCUM) + { + scalar_mode smode = *smode_iter; + 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) - { - 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); + FOR_EACH_MODE_IN_CLASS (smode_iter, MODE_UACCUM) + { + scalar_mode smode = *smode_iter; + 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) @@ -6093,10 +6098,11 @@ init_emit_once (void) 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; + 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); Index: gcc/expr.c =================================================================== --- gcc/expr.c 2017-07-13 09:18:56.007450082 +0100 +++ gcc/expr.c 2017-07-13 09:18:56.812392104 +0100 @@ -559,23 +559,28 @@ convert_mode_scalar (rtx to, rtx from, i } 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; + 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. */ Index: gcc/omp-low.c =================================================================== --- gcc/omp-low.c 2017-07-13 09:18:22.933278054 +0100 +++ gcc/omp-low.c 2017-07-13 09:18:56.813392032 +0100 @@ -3438,16 +3438,18 @@ omp_clause_aligned_alignment (tree claus /* 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; + machine_mode vmode = targetm.vectorize.preferred_simd_mode (mode); if (GET_MODE_CLASS (vmode) != classes[i + 1]) continue; while (vs Index: gcc/optabs.c =================================================================== --- gcc/optabs.c 2017-07-13 09:18:56.346425666 +0100 +++ gcc/optabs.c 2017-07-13 09:18:56.813392032 +0100 @@ -4690,6 +4690,7 @@ expand_float (rtx to, rtx from, int unsi && 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; @@ -4698,12 +4699,14 @@ expand_float (rtx to, rtx from, int unsi 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) + FOR_EACH_MODE_FROM (fmode_iter, to_mode) + if (GET_MODE_PRECISION (from_mode) < GET_MODE_BITSIZE (*fmode_iter) + && can_float_p (*fmode_iter, from_mode, 0) != CODE_FOR_nothing) break; - if (fmode == VOIDmode) + if (fmode_iter.exists ()) + fmode = *fmode_iter; + else { /* There is no such mode. Pretend the target is wide enough. */ fmode = to_mode; @@ -4838,6 +4841,7 @@ expand_fix (rtx to, rtx from, int unsign 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 @@ -4909,66 +4913,70 @@ expand_fix (rtx to, rtx from, int unsign 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); + FOR_EACH_MODE_FROM (fmode_iter, as_a <scalar_mode> (GET_MODE (from))) + { + scalar_mode fmode = *fmode_iter; + 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 (target != to) - emit_move_insn (to, target); + if (fmode != GET_MODE (from)) + from = convert_to_mode (fmode, from, 0); - emit_label (lab2); + /* 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 (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); - } + if (target != to) + emit_move_insn (to, target); - return; - } + 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 Index: gcc/tree-vect-stmts.c =================================================================== --- gcc/tree-vect-stmts.c 2017-07-13 09:18:55.599479728 +0100 +++ gcc/tree-vect-stmts.c 2017-07-13 09:18:56.814391960 +0100 @@ -4195,8 +4195,10 @@ vectorizable_conversion (gimple *stmt, g 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) @@ -4230,8 +4232,9 @@ vectorizable_conversion (gimple *stmt, g 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; if (GET_MODE_SIZE (rhs_mode) > fltsz) break; @@ -4258,10 +4261,13 @@ vectorizable_conversion (gimple *stmt, g 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) Index: gcc/c-family/c-common.c =================================================================== --- gcc/c-family/c-common.c 2017-07-13 09:18:53.993597112 +0100 +++ gcc/c-family/c-common.c 2017-07-13 09:18:56.810392248 +0100 @@ -2155,12 +2155,12 @@ c_common_fixed_point_type_for_size (unsi else mclass = unsignedp ? MODE_UACCUM : MODE_ACCUM; - machine_mode mode; + opt_scalar_mode mode; FOR_EACH_MODE_IN_CLASS (mode, mclass) - if (GET_MODE_IBIT (mode) >= ibit && GET_MODE_FBIT (mode) >= fbit) + if (GET_MODE_IBIT (*mode) >= ibit && GET_MODE_FBIT (*mode) >= fbit) break; - if (mode == VOIDmode || !targetm.scalar_mode_supported_p (mode)) + if (!mode.exists () || !targetm.scalar_mode_supported_p (*mode)) { sorry ("GCC cannot support operators with integer types and " "fixed-point types that have too many integral and " @@ -2168,7 +2168,7 @@ c_common_fixed_point_type_for_size (unsi return NULL_TREE; } - return c_common_type_for_mode (mode, satp); + return c_common_type_for_mode (*mode, satp); } /* Used for communication between c_common_type_for_mode and