From 2b8f5b8a70df80c92331a2a7391f124990beffd6 Mon Sep 17 00:00:00 2001 From: rsandifo Date: Wed, 30 Aug 2017 11:20:19 +0000 Subject: [PATCH] [71/77] Use opt_scalar_mode for mode iterators This patch uses opt_scalar_mode when iterating over scalar modes. 2017-08-30 Richard Sandiford Alan Hayward David Sherwood 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. * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@251522 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 16 ++++++ gcc/c-family/ChangeLog | 7 +++ gcc/c-family/c-common.c | 14 +++-- gcc/coretypes.h | 1 + gcc/emit-rtl.c | 92 +++++++++++++++++--------------- gcc/expr.c | 31 ++++++----- gcc/gdbhooks.py | 3 +- gcc/machmode.h | 7 +++ gcc/omp-low.c | 8 +-- gcc/optabs.c | 137 ++++++++++++++++++++++++++---------------------- gcc/tree-vect-stmts.c | 16 ++++-- 11 files changed, 198 insertions(+), 134 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c4407d6852d..1f5302a704e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -2,6 +2,22 @@ Alan Hayward David Sherwood + * 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. + * 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 + Alan Hayward + David Sherwood + * optabs.c (expand_float): Explicitly check for scalars before using a branching expansion. (expand_fix): Likewise. diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index a715b57f5e9..a294404ec2e 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -2,6 +2,13 @@ Alan Hayward David Sherwood + * c-common.c (c_common_fixed_point_type_for_size): Use opt_scalar_mode + for the mode iterator. + +2017-08-30 Richard Sandiford + Alan Hayward + David Sherwood + * c-lex.c (interpret_fixed): Use SCALAR_TYPE_MODE. * c-common.c (c_build_vec_perm_expr): Likewise. diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 18b2d1acc4f..d959dbc25bb 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -2155,12 +2155,16 @@ c_common_fixed_point_type_for_size (unsigned int ibit, unsigned int fbit, 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 " diff --git a/gcc/coretypes.h b/gcc/coretypes.h index a9f105ceeef..ffe793e409d 100644 --- a/gcc/coretypes.h +++ b/gcc/coretypes.h @@ -59,6 +59,7 @@ class scalar_mode; class scalar_int_mode; class scalar_float_mode; template class opt_mode; +typedef opt_mode opt_scalar_mode; typedef opt_mode opt_scalar_int_mode; typedef opt_mode opt_scalar_float_mode; template class pod_mode; diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index 15c25ec4b4c..3954648027c 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -5885,6 +5885,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. */ @@ -5999,62 +6000,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); + 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) @@ -6087,10 +6092,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.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); diff --git a/gcc/expr.c b/gcc/expr.c index 7e67f3dd8ca..8656f072999 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -559,23 +559,28 @@ convert_mode_scalar (rtx to, rtx from, int unsignedp) } 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. */ diff --git a/gcc/gdbhooks.py b/gcc/gdbhooks.py index 8799e3fbfd9..e5f0cf6f31b 100644 --- a/gcc/gdbhooks.py +++ b/gcc/gdbhooks.py @@ -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) diff --git a/gcc/machmode.h b/gcc/machmode.h index 4586d62b81a..5d84a2eca58 100644 --- a/gcc/machmode.h +++ b/gcc/machmode.h @@ -835,6 +835,13 @@ namespace mode_iterator /* Set mode iterator *ITER to the mode that is two times wider than the current one, if such a mode exists. */ + template + inline void + get_2xwider (opt_mode *iter) + { + *iter = GET_MODE_2XWIDER_MODE (iter->require ()); + } + inline void get_2xwider (machine_mode *iter) { diff --git a/gcc/omp-low.c b/gcc/omp-low.c index 5deb5398c75..080f2f4a994 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -3442,16 +3442,18 @@ omp_clause_aligned_alignment (tree clause) /* 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 diff --git a/gcc/optabs.c b/gcc/optabs.c index d3ceabab8f0..d30e4c6233f 100644 --- a/gcc/optabs.c +++ b/gcc/optabs.c @@ -4692,6 +4692,7 @@ expand_float (rtx to, rtx from, int unsignedp) && is_a (GET_MODE (to), &to_mode) && is_a (GET_MODE (from), &from_mode)) { + opt_scalar_mode fmode_iter; rtx_code_label *label = gen_label_rtx (); rtx temp; REAL_VALUE_TYPE offset; @@ -4700,12 +4701,15 @@ expand_float (rtx to, rtx from, int unsignedp) 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; @@ -4840,6 +4844,7 @@ expand_fix (rtx to, rtx from, int unsignedp) 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 @@ -4911,66 +4916,70 @@ expand_fix (rtx to, rtx from, int unsignedp) if (unsignedp && is_a (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 (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 diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index b8bf5d2b8b0..14089a65659 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -4212,8 +4212,10 @@ vectorizable_conversion (gimple *stmt, gimple_stmt_iterator *gsi, 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) @@ -4247,8 +4249,9 @@ vectorizable_conversion (gimple *stmt, gimple_stmt_iterator *gsi, 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; @@ -4275,10 +4278,13 @@ vectorizable_conversion (gimple *stmt, gimple_stmt_iterator *gsi, 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) -- 2.11.4.GIT