From: Richard Sandiford <richard.sandiford@arm.com>
To: gcc-patches@gcc.gnu.org
Subject: [6/67] Make GET_MODE_WIDER return an opt_mode
Date: Fri, 09 Dec 2016 12:55:00 -0000 [thread overview]
Message-ID: <87r35hntwv.fsf@e105548-lin.cambridge.arm.com> (raw)
In-Reply-To: <87h96dp8u6.fsf@e105548-lin.cambridge.arm.com> (Richard Sandiford's message of "Fri, 09 Dec 2016 12:48:01 +0000")
GET_MODE_WIDER previously returned VOIDmode if no wider
mode exists. That would cause problems with stricter mode
classes, since VOIDmode isn't for example a valid scalar
integer or floating-point mode. This patch instead makes
it return a new opt_mode<T> class, which holds either
a T or nothing.
gcc/
2016-11-24 Richard Sandiford <richard.sandiford@arm.com>
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>
* coretypes.h (opt_mode): New class.
* machmode.h (opt_mode): Likewise.
(opt_mode::else_void): New function.
(opt_mode::operator *): Likewise.
(opt_mode::exists): Likewise.
(GET_MODE_WIDER_MODE): Turn into a function and return an opt_mode.
(GET_MODE_2XWIDER_MODE): Likewise.
(mode_iterator::get_wider): Update accordingly.
(mode_iterator::get_2xwider): Likewise.
(mode_iterator::get_known_wider): Likewise, turning into a template.
* combine.c (make_extraction): Update use of GET_MODE_WIDER_MODE,
forcing a wider mode to exist.
* config/cr16/cr16.h (LONG_REG_P): Likewise.
* rtlanal.c (init_num_sign_bit_copies_in_rep): Likewise.
* config/c6x/c6x.c (c6x_rtx_costs): Update use of
GET_MODE_2XWIDER_MODE, forcing a wider mode to exist.
* lower-subreg.c (init_lower_subreg): Likewise.
* optabs-libfuncs.c (init_sync_libfuncs_1): Likewise, but not
on the final iteration.
* config/i386/i386.c (ix86_expand_set_or_movmem): Check whether
a wider mode exists before asking for a move pattern.
(get_mode_wider_vector): Update use of GET_MODE_WIDER_MODE,
forcing a wider mode to exist.
(expand_vselect_vconcat): Likewise GET_MODE_2XWIDER_MODE.
* config/ia64/ia64.c (expand_vselect_vconcat): Check whether
a 2x wider mode exists.
* config/mips/mips.c (mips_expand_vselect_vconcat): Likewise.
* expmed.c (init_expmed_one_mode): Update use of GET_MODE_WIDER_MODE.
Avoid checking for a MODE_INT if we already know the mode is not a
SCALAR_INT_MODE_P.
(extract_high_half): Update use of GET_MODE_WIDER_MODE,
forcing a wider mode to exist.
(expmed_mult_highpart_optab): Likewise.
(expmed_mult_highpart): Likewise.
* expr.c (expand_expr_real_2): Update use of GET_MODE_WIDER_MODE,
using else_void.
* lto-streamer-in.c (lto_input_mode_table): Likewise.
* optabs-query.c (find_widening_optab_handler_and_mode): Likewise.
* stor-layout.c (bit_field_mode_iterator::next_mode): Likewise.
* internal-fn.c (expand_mul_overflow): Update use of
GET_MODE_WIDER_MODE.
* tree-ssa-math-opts.c (convert_mult_to_widen): Likewise.
(convert_plusminus_to_widen): Likewise.
* omp-low.c (omp_clause_aligned_alignment): Likewise.
* tree-switch-conversion.c (array_value_type): Likewise.
* var-tracking.c (emit_note_insn_var_location): Likewise.
* tree-vrp.c (simplify_float_conversion_using_ranges): Likewise.
Return false inside rather than outside the loop if no wider mode
exists
* optabs.c (expand_binop): Update use of GET_MODE_WIDER_MODE
and GET_MODE_2XWIDER_MODE
(can_compare_p): Use else_void.
gcc/ada/
2016-11-24 Richard Sandiford <richard.sandiford@arm.com>
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>
* gcc-interface/decl.c (validate_size): Update use of
GET_MODE_WIDER_MODE, forcing a wider mode to exist.
diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c
index 18ec63d..d3bee34 100644
--- a/gcc/ada/gcc-interface/decl.c
+++ b/gcc/ada/gcc-interface/decl.c
@@ -8528,7 +8528,7 @@ validate_size (Uint uint_size, tree gnu_type, Entity_Id gnat_object,
{
machine_mode p_mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
while (!targetm.valid_pointer_mode (p_mode))
- p_mode = GET_MODE_WIDER_MODE (p_mode);
+ p_mode = *GET_MODE_WIDER_MODE (p_mode);
type_size = bitsize_int (GET_MODE_BITSIZE (p_mode));
}
diff --git a/gcc/combine.c b/gcc/combine.c
index 8b08b14..e8e0b3f 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -7592,10 +7592,7 @@ make_extraction (machine_mode mode, rtx inner, HOST_WIDE_INT pos,
wanted_inner_mode = smallest_mode_for_size (len, MODE_INT);
while (pos % GET_MODE_BITSIZE (wanted_inner_mode) + len
> GET_MODE_BITSIZE (wanted_inner_mode))
- {
- wanted_inner_mode = GET_MODE_WIDER_MODE (wanted_inner_mode);
- gcc_assert (wanted_inner_mode != VOIDmode);
- }
+ wanted_inner_mode = *GET_MODE_WIDER_MODE (wanted_inner_mode);
}
orig_pos = pos;
diff --git a/gcc/config/c6x/c6x.c b/gcc/config/c6x/c6x.c
index fcb5b01..7e059b2 100644
--- a/gcc/config/c6x/c6x.c
+++ b/gcc/config/c6x/c6x.c
@@ -6063,7 +6063,7 @@ c6x_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno, int *total,
/* Recognize a mult_highpart operation. */
if ((mode == HImode || mode == SImode)
&& GET_CODE (XEXP (x, 0)) == LSHIFTRT
- && GET_MODE (XEXP (x, 0)) == GET_MODE_2XWIDER_MODE (mode)
+ && GET_MODE (XEXP (x, 0)) == *GET_MODE_2XWIDER_MODE (mode)
&& GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT
&& GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
&& INTVAL (XEXP (XEXP (x, 0), 1)) == GET_MODE_BITSIZE (mode))
diff --git a/gcc/config/cr16/cr16.h b/gcc/config/cr16/cr16.h
index 2d08c2b..2dcad94 100644
--- a/gcc/config/cr16/cr16.h
+++ b/gcc/config/cr16/cr16.h
@@ -197,9 +197,7 @@ while (0)
/* Returns 1 if the register is longer than word size, 0 otherwise. */
#define LONG_REG_P(REGNO) \
- (HARD_REGNO_NREGS (REGNO, \
- GET_MODE_WIDER_MODE (smallest_mode_for_size \
- (BITS_PER_WORD, MODE_INT))) == 1)
+ (HARD_REGNO_NREGS (REGNO, *GET_MODE_WIDER_MODE (word_mode)) == 1)
#define HARD_REGNO_NREGS(REGNO, MODE) \
((REGNO >= CR16_FIRST_DWORD_REGISTER) \
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 616b514..0c58dae 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -27440,6 +27440,7 @@ ix86_expand_set_or_movmem (rtx dst, rtx src, rtx count_exp, rtx val_exp,
bool need_zero_guard = false;
bool noalign;
machine_mode move_mode = VOIDmode;
+ machine_mode wider_mode;
int unroll_factor = 1;
/* TODO: Once value ranges are available, fill in proper data. */
unsigned HOST_WIDE_INT min_size = 0;
@@ -27533,9 +27534,9 @@ ix86_expand_set_or_movmem (rtx dst, rtx src, rtx count_exp, rtx val_exp,
unroll_factor = 4;
/* Find the widest supported mode. */
move_mode = word_mode;
- while (optab_handler (mov_optab, GET_MODE_WIDER_MODE (move_mode))
- != CODE_FOR_nothing)
- move_mode = GET_MODE_WIDER_MODE (move_mode);
+ while (GET_MODE_WIDER_MODE (move_mode).exists (&wider_mode)
+ && optab_handler (mov_optab, wider_mode) != CODE_FOR_nothing)
+ move_mode = wider_mode;
/* Find the corresponding vector mode with the same size as MOVE_MODE.
MOVE_MODE is an integer mode at the moment (SI, DI, TI, etc.). */
@@ -42354,7 +42355,7 @@ static inline machine_mode
get_mode_wider_vector (machine_mode o)
{
/* ??? Rely on the ordering that genmodes.c gives to vectors. */
- machine_mode n = GET_MODE_WIDER_MODE (o);
+ machine_mode n = *GET_MODE_WIDER_MODE (o);
gcc_assert (GET_MODE_NUNITS (o) == GET_MODE_NUNITS (n) * 2);
gcc_assert (GET_MODE_SIZE (o) == GET_MODE_SIZE (n));
return n;
@@ -45616,7 +45617,8 @@ expand_vselect_vconcat (rtx target, rtx op0, rtx op1,
if (vselect_insn == NULL_RTX)
init_vselect_insn ();
- v2mode = GET_MODE_2XWIDER_MODE (GET_MODE (op0));
+ if (!GET_MODE_2XWIDER_MODE (GET_MODE (op0)).exists (&v2mode))
+ return false;
x = XEXP (SET_SRC (PATTERN (vselect_insn)), 0);
PUT_MODE (x, v2mode);
XEXP (x, 0) = op0;
diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c
index 21953d1..d43edc8 100644
--- a/gcc/config/ia64/ia64.c
+++ b/gcc/config/ia64/ia64.c
@@ -11297,7 +11297,8 @@ expand_vselect_vconcat (rtx target, rtx op0, rtx op1,
machine_mode v2mode;
rtx x;
- v2mode = GET_MODE_2XWIDER_MODE (GET_MODE (op0));
+ if (!GET_MODE_2XWIDER_MODE (GET_MODE (op0)).exists (&v2mode))
+ return false;
x = gen_rtx_VEC_CONCAT (v2mode, op0, op1);
return expand_vselect (target, x, perm, nelt);
}
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 7eca000..6c08aed 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -21079,7 +21079,8 @@ mips_expand_vselect_vconcat (rtx target, rtx op0, rtx op1,
machine_mode v2mode;
rtx x;
- v2mode = GET_MODE_2XWIDER_MODE (GET_MODE (op0));
+ if (!GET_MODE_2XWIDER_MODE (GET_MODE (op0)).exists (&v2mode))
+ return false;
x = gen_rtx_VEC_CONCAT (v2mode, op0, op1);
return mips_expand_vselect (target, x, perm, nelt);
}
diff --git a/gcc/coretypes.h b/gcc/coretypes.h
index f26c1a0..9f81995 100644
--- a/gcc/coretypes.h
+++ b/gcc/coretypes.h
@@ -56,6 +56,7 @@ struct rtx_def;
typedef struct rtx_def *rtx;
typedef const struct rtx_def *const_rtx;
class machine_mode;
+template<typename> class opt_mode;
/* Subclasses of rtx_def, using indentation to show the class
hierarchy, along with the relevant invariant.
diff --git a/gcc/expmed.c b/gcc/expmed.c
index 9a0aa7e..737588b 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -206,11 +206,10 @@ init_expmed_one_mode (struct init_expmed_rtl *all,
{
FOR_EACH_MODE_IN_CLASS (mode_from, MODE_INT)
init_expmed_one_conv (all, mode, mode_from, speed);
- }
- if (GET_MODE_CLASS (mode) == MODE_INT)
- {
- machine_mode wider_mode = GET_MODE_WIDER_MODE (mode);
- if (wider_mode != VOIDmode)
+
+ machine_mode wider_mode;
+ if (GET_MODE_CLASS (mode) == MODE_INT
+ && GET_MODE_WIDER_MODE (mode).exists (&wider_mode))
{
PUT_MODE (all->zext, wider_mode);
PUT_MODE (all->wide_mult, wider_mode);
@@ -3578,7 +3577,7 @@ extract_high_half (machine_mode mode, rtx op)
gcc_assert (!SCALAR_FLOAT_MODE_P (mode));
- wider_mode = GET_MODE_WIDER_MODE (mode);
+ wider_mode = *GET_MODE_WIDER_MODE (mode);
op = expand_shift (RSHIFT_EXPR, wider_mode, op,
GET_MODE_BITSIZE (mode), 0, 1);
return convert_modes (mode, wider_mode, op, 0);
@@ -3600,7 +3599,7 @@ expmed_mult_highpart_optab (machine_mode mode, rtx op0, rtx op1,
gcc_assert (!SCALAR_FLOAT_MODE_P (mode));
- wider_mode = GET_MODE_WIDER_MODE (mode);
+ wider_mode = *GET_MODE_WIDER_MODE (mode);
size = GET_MODE_BITSIZE (mode);
/* Firstly, try using a multiplication insn that only generates the needed
@@ -3706,7 +3705,7 @@ static rtx
expmed_mult_highpart (machine_mode mode, rtx op0, rtx op1,
rtx target, int unsignedp, int max_cost)
{
- machine_mode wider_mode = GET_MODE_WIDER_MODE (mode);
+ machine_mode wider_mode = *GET_MODE_WIDER_MODE (mode);
unsigned HOST_WIDE_INT cnst1;
int extra_cost;
bool sign_adjust = false;
diff --git a/gcc/expr.c b/gcc/expr.c
index 1bcf6c6..a3a3e86 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -9090,7 +9090,7 @@ expand_expr_real_2 (sepops ops, rtx target, machine_mode tmode,
&& target
&& REG_P (target)
&& ! unsignedp
- && mode == GET_MODE_WIDER_MODE (word_mode)
+ && mode == GET_MODE_WIDER_MODE (word_mode).else_void ()
&& GET_MODE_SIZE (mode) == 2 * GET_MODE_SIZE (word_mode)
&& TREE_CONSTANT (treeop1)
&& TREE_CODE (treeop0) == SSA_NAME)
diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c
index 0d91b8e..3dbd2a1 100644
--- a/gcc/internal-fn.c
+++ b/gcc/internal-fn.c
@@ -1468,14 +1468,14 @@ expand_mul_overflow (location_t loc, tree lhs, tree arg0, tree arg1,
struct separate_ops ops;
int prec = GET_MODE_PRECISION (mode);
machine_mode hmode = mode_for_size (prec / 2, MODE_INT, 1);
+ machine_mode wmode;
ops.op0 = make_tree (type, op0);
ops.op1 = make_tree (type, op1);
ops.op2 = NULL_TREE;
ops.location = loc;
- if (GET_MODE_2XWIDER_MODE (mode) != VOIDmode
- && targetm.scalar_mode_supported_p (GET_MODE_2XWIDER_MODE (mode)))
+ if (GET_MODE_2XWIDER_MODE (mode).exists (&wmode)
+ && targetm.scalar_mode_supported_p (wmode))
{
- machine_mode wmode = GET_MODE_2XWIDER_MODE (mode);
ops.code = WIDEN_MULT_EXPR;
ops.type
= build_nonstandard_integer_type (GET_MODE_PRECISION (wmode), uns);
diff --git a/gcc/lower-subreg.c b/gcc/lower-subreg.c
index ca4582f..d378542 100644
--- a/gcc/lower-subreg.c
+++ b/gcc/lower-subreg.c
@@ -266,7 +266,7 @@ init_lower_subreg (void)
memset (this_target_lower_subreg, 0, sizeof (*this_target_lower_subreg));
- twice_word_mode = GET_MODE_2XWIDER_MODE (word_mode);
+ twice_word_mode = *GET_MODE_2XWIDER_MODE (word_mode);
rtxes.target = gen_rtx_REG (word_mode, LAST_VIRTUAL_REGISTER + 1);
rtxes.source = gen_rtx_REG (word_mode, LAST_VIRTUAL_REGISTER + 2);
diff --git a/gcc/lto-streamer-in.c b/gcc/lto-streamer-in.c
index 69d87e6..578b10f 100644
--- a/gcc/lto-streamer-in.c
+++ b/gcc/lto-streamer-in.c
@@ -1555,7 +1555,7 @@ lto_input_mode_table (struct lto_file_decl_data *file_data)
: GET_CLASS_NARROWEST_MODE (mclass);
pass ? mr < MAX_MACHINE_MODE : mr != VOIDmode;
pass ? mr = (machine_mode_enum) (mr + 1)
- : mr = GET_MODE_WIDER_MODE (mr))
+ : mr = GET_MODE_WIDER_MODE (mr).else_void ())
if (GET_MODE_CLASS (mr) != mclass
|| GET_MODE_SIZE (mr) != size
|| GET_MODE_PRECISION (mr) != prec
diff --git a/gcc/machmode.h b/gcc/machmode.h
index be389a2..44a8ad4 100644
--- a/gcc/machmode.h
+++ b/gcc/machmode.h
@@ -183,6 +183,60 @@ extern const unsigned char mode_class[NUM_MACHINE_MODES];
#define POINTER_BOUNDS_MODE_P(MODE) \
(GET_MODE_CLASS (MODE) == MODE_POINTER_BOUNDS)
+/* An optional T (i.e. a T or nothing), where T is some form of mode class.
+ operator * gives the T value. */
+template<typename T>
+class opt_mode
+{
+public:
+ ALWAYS_INLINE opt_mode () : m_mode (E_VOIDmode) {}
+ ALWAYS_INLINE opt_mode (const T &m) : m_mode (m) {}
+ machine_mode_enum else_void () const;
+ T operator * () const;
+
+ /* Return true if the object contains a T rather than nothing. */
+ ALWAYS_INLINE bool exists () const { return m_mode != E_VOIDmode; }
+ template<typename U> bool exists (U *) const;
+
+private:
+ machine_mode_enum m_mode;
+};
+
+/* If the object contains a T, return its enum value, otherwise return
+ E_VOIDmode. */
+
+template<typename T>
+ALWAYS_INLINE machine_mode_enum
+opt_mode<T>::else_void () const
+{
+ return m_mode;
+}
+
+/* Assert that the object contains a T and return it. */
+
+template<typename T>
+inline T
+opt_mode<T>::operator * () const
+{
+ gcc_checking_assert (m_mode != E_VOIDmode);
+ return T::from_int (m_mode);
+}
+
+/* Return true if the object contains a T, storing it in *MODE if so. */
+
+template<typename T>
+template<typename U>
+inline bool
+opt_mode<T>::exists (U *mode) const
+{
+ if (m_mode != E_VOIDmode)
+ {
+ *mode = T::from_int (m_mode);
+ return true;
+ }
+ return false;
+}
+
/* Represents a general machine mode (scalar or non-scalar). */
class machine_mode
{
@@ -336,15 +390,28 @@ extern const unsigned HOST_WIDE_INT mode_mask_array[NUM_MACHINE_MODES];
/* Get the next wider natural mode (eg, QI -> HI -> SI -> DI -> TI). */
-extern const unsigned char mode_wider[NUM_MACHINE_MODES];
-#define GET_MODE_WIDER_MODE(MODE) \
- (machine_mode ((machine_mode_enum) mode_wider[MODE]))
+template<typename T>
+ALWAYS_INLINE opt_mode<T>
+GET_MODE_WIDER_MODE (const T &m)
+{
+ machine_mode_enum wider = (machine_mode_enum) mode_wider[m];
+ if (wider != E_VOIDmode)
+ return T::from_int (wider);
+ return opt_mode<T> ();
+}
/* For scalars, this is a mode with twice the precision. For vectors,
this is a mode with the same inner mode but with twice the elements. */
-extern const unsigned char mode_2xwider[NUM_MACHINE_MODES];
-#define GET_MODE_2XWIDER_MODE(MODE) \
- (machine_mode ((machine_mode_enum) mode_2xwider[MODE]))
+
+template<typename T>
+ALWAYS_INLINE opt_mode<T>
+GET_MODE_2XWIDER_MODE (const T &m)
+{
+ machine_mode_enum wider = (machine_mode_enum) mode_2xwider[m];
+ if (wider != E_VOIDmode)
+ return T::from_int (wider);
+ return opt_mode<T> ();
+}
/* Get the complex mode from the component mode. */
extern const unsigned char mode_complex[NUM_MACHINE_MODES];
@@ -483,17 +550,17 @@ namespace mode_iterator
inline void
get_wider (machine_mode *iter)
{
- *iter = GET_MODE_WIDER_MODE (*iter);
+ *iter = GET_MODE_WIDER_MODE (*iter).else_void ();
}
/* Set mode iterator *ITER to the next widest mode in the same class.
Such a mode is known to exist. */
+ template<typename T>
inline void
- get_known_wider (machine_mode *iter)
+ get_known_wider (T *iter)
{
- *iter = GET_MODE_WIDER_MODE (*iter);
- gcc_checking_assert (*iter != VOIDmode);
+ *iter = *GET_MODE_WIDER_MODE (*iter);
}
/* Set mode iterator *ITER to the mode that is two times wider than the
@@ -502,7 +569,7 @@ namespace mode_iterator
inline void
get_2xwider (machine_mode *iter)
{
- *iter = GET_MODE_2XWIDER_MODE (*iter);
+ *iter = GET_MODE_2XWIDER_MODE (*iter).else_void ();
}
}
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index 3041a67..13f3435 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -4314,8 +4314,8 @@ omp_clause_aligned_alignment (tree clause)
continue;
while (vs
&& GET_MODE_SIZE (vmode) < vs
- && GET_MODE_2XWIDER_MODE (vmode) != VOIDmode)
- vmode = GET_MODE_2XWIDER_MODE (vmode);
+ && GET_MODE_2XWIDER_MODE (vmode).exists ())
+ vmode = *GET_MODE_2XWIDER_MODE (vmode);
tree type = lang_hooks.types.type_for_mode (mode, 1);
if (type == NULL_TREE || TYPE_MODE (type) != mode)
diff --git a/gcc/optabs-libfuncs.c b/gcc/optabs-libfuncs.c
index 79a07d6..9d9ffbd 100644
--- a/gcc/optabs-libfuncs.c
+++ b/gcc/optabs-libfuncs.c
@@ -918,9 +918,10 @@ init_sync_libfuncs_1 (optab tab, const char *base, int max)
mode = QImode;
for (i = 1; i <= max; i *= 2)
{
+ if (i > 1)
+ mode = *GET_MODE_2XWIDER_MODE (mode);
buf[len + 1] = '0' + i;
set_optab_libfunc (tab, mode, buf);
- mode = GET_MODE_2XWIDER_MODE (mode);
}
}
diff --git a/gcc/optabs-query.c b/gcc/optabs-query.c
index b60362a..fdde578 100644
--- a/gcc/optabs-query.c
+++ b/gcc/optabs-query.c
@@ -425,7 +425,7 @@ find_widening_optab_handler_and_mode (optab op, machine_mode to_mode,
for (; (permit_non_widening || from_mode != to_mode)
&& GET_MODE_SIZE (from_mode) <= GET_MODE_SIZE (to_mode)
&& from_mode != VOIDmode;
- from_mode = GET_MODE_WIDER_MODE (from_mode))
+ from_mode = GET_MODE_WIDER_MODE (from_mode).else_void ())
{
enum insn_code handler = widening_optab_handler (op, to_mode,
from_mode);
diff --git a/gcc/optabs.c b/gcc/optabs.c
index 6c859b2..5dab1b4 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -1184,13 +1184,13 @@ expand_binop (machine_mode mode, optab binoptab, rtx op0, rtx op1,
takes operands of this mode and makes a wider mode. */
if (binoptab == smul_optab
- && GET_MODE_2XWIDER_MODE (mode) != VOIDmode
- && (widening_optab_handler ((unsignedp ? umul_widen_optab
- : smul_widen_optab),
- GET_MODE_2XWIDER_MODE (mode), mode)
- != CODE_FOR_nothing))
+ && GET_MODE_2XWIDER_MODE (mode).exists (&wider_mode)
+ && (convert_optab_handler ((unsignedp
+ ? umul_widen_optab
+ : smul_widen_optab),
+ wider_mode, mode) != CODE_FOR_nothing))
{
- temp = expand_binop (GET_MODE_2XWIDER_MODE (mode),
+ temp = expand_binop (wider_mode,
unsignedp ? umul_widen_optab : smul_widen_optab,
op0, op1, NULL_RTX, unsignedp, OPTAB_DIRECT);
@@ -1251,14 +1251,14 @@ expand_binop (machine_mode mode, optab binoptab, rtx op0, rtx op1,
&& methods != OPTAB_DIRECT && methods != OPTAB_LIB)
FOR_EACH_WIDER_MODE (wider_mode, mode)
{
+ machine_mode next_mode;
if (optab_handler (binoptab, wider_mode) != CODE_FOR_nothing
|| (binoptab == smul_optab
- && GET_MODE_WIDER_MODE (wider_mode) != VOIDmode
+ && GET_MODE_WIDER_MODE (wider_mode).exists (&next_mode)
&& (find_widening_optab_handler ((unsignedp
? umul_widen_optab
: smul_widen_optab),
- GET_MODE_WIDER_MODE (wider_mode),
- mode, 0)
+ next_mode, mode, 0)
!= CODE_FOR_nothing)))
{
rtx xop0 = op0, xop1 = op1;
@@ -3699,7 +3699,7 @@ can_compare_p (enum rtx_code code, machine_mode mode,
&& optab_handler (cmov_optab, mode) != CODE_FOR_nothing)
return 1;
- mode = GET_MODE_WIDER_MODE (mode);
+ mode = GET_MODE_WIDER_MODE (mode).else_void ();
PUT_MODE (test, mode);
}
while (mode != VOIDmode);
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
index a1070fb..92b7580 100644
--- a/gcc/rtlanal.c
+++ b/gcc/rtlanal.c
@@ -5613,13 +5613,15 @@ init_num_sign_bit_copies_in_rep (void)
/* Currently, it is assumed that TARGET_MODE_REP_EXTENDED
extends to the next widest mode. */
gcc_assert (targetm.mode_rep_extended (mode, in_mode) == UNKNOWN
- || GET_MODE_WIDER_MODE (mode) == in_mode);
+ || *GET_MODE_WIDER_MODE (mode) == in_mode);
/* We are in in_mode. Count how many bits outside of mode
have to be copies of the sign-bit. */
FOR_EACH_MODE (i, mode, in_mode)
{
- machine_mode wider = GET_MODE_WIDER_MODE (i);
+ /* This must always exist (for the last iteration it will be
+ IN_MODE). */
+ machine_mode wider = *GET_MODE_WIDER_MODE (i);
if (targetm.mode_rep_extended (i, wider) == SIGN_EXTEND
/* We can only check sign-bit copies starting from the
diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c
index 954e046..834cf8b 100644
--- a/gcc/stor-layout.c
+++ b/gcc/stor-layout.c
@@ -2709,7 +2709,8 @@ bit_field_mode_iterator
bool
bit_field_mode_iterator::next_mode (machine_mode *out_mode)
{
- for (; m_mode != VOIDmode; m_mode = GET_MODE_WIDER_MODE (m_mode))
+ for (; m_mode != VOIDmode;
+ m_mode = GET_MODE_WIDER_MODE (m_mode).else_void ())
{
unsigned int unit = GET_MODE_BITSIZE (m_mode);
@@ -2746,7 +2747,7 @@ bit_field_mode_iterator::next_mode (machine_mode *out_mode)
break;
*out_mode = m_mode;
- m_mode = GET_MODE_WIDER_MODE (m_mode);
+ m_mode = GET_MODE_WIDER_MODE (m_mode).else_void ();
m_count++;
return true;
}
diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c
index b3edcc0..e0883ff 100644
--- a/gcc/tree-ssa-math-opts.c
+++ b/gcc/tree-ssa-math-opts.c
@@ -3160,8 +3160,8 @@ convert_mult_to_widen (gimple *stmt, gimple_stmt_iterator *gsi)
|| (TYPE_UNSIGNED (type2)
&& TYPE_PRECISION (type2) == GET_MODE_PRECISION (from_mode)))
{
- from_mode = GET_MODE_WIDER_MODE (from_mode);
- if (GET_MODE_SIZE (to_mode) <= GET_MODE_SIZE (from_mode))
+ if (!GET_MODE_WIDER_MODE (from_mode).exists (&from_mode)
+ || GET_MODE_SIZE (to_mode) <= GET_MODE_SIZE (from_mode))
return false;
}
@@ -3342,8 +3342,8 @@ convert_plusminus_to_widen (gimple_stmt_iterator *gsi, gimple *stmt,
|| (from_unsigned2
&& TYPE_PRECISION (type2) == GET_MODE_PRECISION (from_mode)))
{
- from_mode = GET_MODE_WIDER_MODE (from_mode);
- if (GET_MODE_SIZE (from_mode) >= GET_MODE_SIZE (to_mode))
+ if (!GET_MODE_WIDER_MODE (from_mode).exists (&from_mode)
+ || GET_MODE_SIZE (from_mode) >= GET_MODE_SIZE (to_mode))
return false;
}
diff --git a/gcc/tree-switch-conversion.c b/gcc/tree-switch-conversion.c
index 8b64f4b..62c3a78 100644
--- a/gcc/tree-switch-conversion.c
+++ b/gcc/tree-switch-conversion.c
@@ -989,8 +989,7 @@ array_value_type (gswitch *swtch, tree type, int num,
if (sign == 1)
sign = 0;
- mode = GET_MODE_WIDER_MODE (mode);
- if (mode == VOIDmode
+ if (!GET_MODE_WIDER_MODE (mode).exists (&mode)
|| GET_MODE_SIZE (mode) >= GET_MODE_SIZE (type_mode))
return type;
}
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 600634d..f3322b6 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -9995,7 +9995,7 @@ simplify_float_conversion_using_ranges (gimple_stmt_iterator *gsi,
else
{
mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
- do
+ for (;;)
{
/* If we cannot do a signed conversion to float from mode
or if the value-range does not fit in the signed type
@@ -10004,15 +10004,12 @@ simplify_float_conversion_using_ranges (gimple_stmt_iterator *gsi,
&& range_fits_type_p (vr, GET_MODE_PRECISION (mode), SIGNED))
break;
- mode = GET_MODE_WIDER_MODE (mode);
/* But do not widen the input. Instead leave that to the
optabs expansion code. */
- if (GET_MODE_PRECISION (mode) > TYPE_PRECISION (TREE_TYPE (rhs1)))
+ if (!GET_MODE_WIDER_MODE (mode).exists (&mode)
+ || GET_MODE_PRECISION (mode) > TYPE_PRECISION (TREE_TYPE (rhs1)))
return false;
}
- while (mode != VOIDmode);
- if (mode == VOIDmode)
- return false;
}
/* It works, insert a truncation or sign-change before the
diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c
index 74101d2..cd29dc6 100644
--- a/gcc/var-tracking.c
+++ b/gcc/var-tracking.c
@@ -8705,12 +8705,11 @@ emit_note_insn_var_location (variable **varp, emit_note_data *data)
last_limit = offsets[n_var_parts] + GET_MODE_SIZE (mode);
/* Attempt to merge adjacent registers or memory. */
- wider_mode = GET_MODE_WIDER_MODE (mode);
for (j = i + 1; j < var->n_var_parts; j++)
if (last_limit <= VAR_PART_OFFSET (var, j))
break;
if (j < var->n_var_parts
- && wider_mode != VOIDmode
+ && GET_MODE_WIDER_MODE (mode).exists (&wider_mode)
&& var->var_part[j].cur_loc
&& mode == GET_MODE (var->var_part[j].cur_loc)
&& (REG_P (loc[n_var_parts]) || MEM_P (loc[n_var_parts]))
next prev parent reply other threads:[~2016-12-09 12:55 UTC|newest]
Thread overview: 79+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-12-09 12:48 [0/67] Add wrapper classes for machine_modes Richard Sandiford
2016-12-09 12:50 ` [1/67] Add an E_ prefix to mode names and update case statements Richard Sandiford
2016-12-09 12:52 ` [2/67] Make machine_mode a class Richard Sandiford
2016-12-15 22:34 ` Trevor Saunders
2016-12-09 12:53 ` [3/67] Add GDB pretty printer for machine mode classes Richard Sandiford
2016-12-09 12:54 ` [4/67] Add FOR_EACH iterators for modes Richard Sandiford
2016-12-09 12:55 ` [5/67] Small tweak to array_value_type Richard Sandiford
2016-12-09 12:55 ` Richard Sandiford [this message]
2016-12-09 12:57 ` [7/67] Add scalar_float_mode Richard Sandiford
2016-12-09 14:19 ` David Malcolm
2016-12-09 14:30 ` Richard Sandiford
2016-12-09 12:57 ` [8/67] Simplify gen_trunc/extend_conv_libfunc Richard Sandiford
2016-12-09 12:58 ` [9/67] Add SCALAR_FLOAT_TYPE_MODE Richard Sandiford
2016-12-09 12:59 ` [10/67] Make assemble_real take a scalar_float_mode Richard Sandiford
2016-12-09 13:00 ` [11/67] Add a float_mode_for_size helper function Richard Sandiford
2016-12-09 13:00 ` [12/67] Use opt_scalar_float_mode when iterating over float modes Richard Sandiford
2016-12-09 13:00 ` [0/67] Add wrapper classes for machine_modes Richard Biener
2016-12-09 13:54 ` Richard Sandiford
2016-12-09 13:01 ` [13/67] Make floatn_mode return an opt_scalar_float_mode Richard Sandiford
2016-12-09 13:02 ` [14/67] Make libgcc_floating_mode_supported_p take a scalar_float_mode Richard Sandiford
2016-12-09 13:03 ` [15/67] Add scalar_int_mode Richard Sandiford
2016-12-09 13:03 ` [16/67] Add scalar_int_mode_pod Richard Sandiford
2016-12-09 13:04 ` [17/67] Add an int_mode_for_size helper function Richard Sandiford
2016-12-09 13:05 ` [18/67] Make int_mode_for_mode return an opt_scalar_int_mode Richard Sandiford
2016-12-09 13:05 ` [19/67] Add a smallest_int_mode_for_size helper function Richard Sandiford
2016-12-09 13:06 ` [20/67] Replace MODE_INT checks with is_int_mode Richard Sandiford
2016-12-09 13:07 ` [22/67] Replace !VECTOR_MODE_P with is_a <scalar_int_mode> Richard Sandiford
2016-12-09 13:07 ` [21/67] Replace SCALAR_INT_MODE_P checks " Richard Sandiford
2016-12-09 13:08 ` [23/67] Replace != VOIDmode " Richard Sandiford
2016-12-09 13:08 ` [24/67] Replace a != BLKmode check " Richard Sandiford
2016-12-09 13:22 ` Richard Biener
2016-12-09 14:42 ` Richard Sandiford
2016-12-09 13:09 ` [25/67] Use is_a <scalar_int_mode> for bitmask optimisations Richard Sandiford
2016-12-09 13:10 ` [26/67] Use is_a <scalar_int_mode> in subreg/extract simplifications Richard Sandiford
2016-12-09 13:10 ` [27/67] Use is_a <scalar_int_mode> before LOAD_EXTEND_OP Richard Sandiford
2016-12-09 13:11 ` [28/67] Use is_a <scalar_int_mode> for miscellaneous types of test Richard Sandiford
2016-12-09 13:12 ` [29/67] Make some *_loc_descriptor helpers take scalar_int_mode Richard Sandiford
2016-12-09 13:12 ` [30/67] Use scalar_int_mode for doubleword splits Richard Sandiford
2016-12-09 13:13 ` [31/67] Use scalar_int_mode for move2add Richard Sandiford
2016-12-09 13:14 ` [32/67] Check is_a <scalar_int_mode> before calling valid_pointer_mode Richard Sandiford
2016-12-09 13:14 ` [33/67] Add a NARROWEST_INT_MODE macro Richard Sandiford
2016-12-09 13:15 ` [34/67] Add a SCALAR_INT_TYPE_MODE macro Richard Sandiford
2016-12-09 13:16 ` [35/67] Add uses of as_a <scalar_int_mode> Richard Sandiford
2016-12-09 13:16 ` [36/67] Use scalar_int_mode in the RTL iv routines Richard Sandiford
2016-12-09 13:17 ` [37/67] Use scalar_int_mode when emitting cstores Richard Sandiford
2016-12-09 13:17 ` [38/67] Move SCALAR_INT_MODE_P out of strict_volatile_bitfield_p Richard Sandiford
2016-12-09 13:18 ` [39/67] Two changes to the get_best_mode interface Richard Sandiford
2016-12-09 13:19 ` [40/67] Use scalar_int_mode for extraction_insn fields Richard Sandiford
2016-12-09 13:20 ` [41/67] Split scalar integer handling out of force_to_mode Richard Sandiford
2016-12-09 13:20 ` [42/67] Use scalar_int_mode in simplify_shift_const_1 Richard Sandiford
2016-12-09 13:22 ` [44/67] Make simplify_and_const_int take a scalar_int_mode Richard Sandiford
2016-12-09 13:22 ` [43/67] Use scalar_int_mode in simplify_comparison Richard Sandiford
2016-12-09 13:23 ` [46/67] Make widest_int_mode_for_size return a scalar_int_mode Richard Sandiford
2016-12-09 13:23 ` [45/67] Make extract_left_shift take " Richard Sandiford
2016-12-09 13:24 ` [47/67] Make subroutines of nonzero_bits operate on scalar_int_mode Richard Sandiford
2016-12-09 13:25 ` [48/67] Make subroutines of num_sign_bit_copies " Richard Sandiford
2016-12-09 13:25 ` [49/67] Simplify nonzero/num_sign_bits hooks Richard Sandiford
2016-12-09 13:28 ` [50/67] Add helper routines for SUBREG_PROMOTED_VAR_P subregs Richard Sandiford
2016-12-09 13:30 ` [52/67] Use scalar_int_mode in extract/store_bit_field Richard Sandiford
2016-12-09 13:30 ` [51/67] Use opt_scalar_int_mode when iterating over integer modes Richard Sandiford
2016-12-09 13:31 ` [54/67] Add explicit int checks for alternative optab implementations Richard Sandiford
2016-12-09 13:31 ` [53/67] Pass a mode to const_scalar_mask_from_tree Richard Sandiford
2016-12-09 13:33 ` [56/67] Use the more specific type when two modes are known to be equal Richard Sandiford
2016-12-09 13:33 ` [55/67] Use scalar_int_mode in simplify_const_unary_operation Richard Sandiford
2016-12-09 13:34 ` [57/67] Use scalar_int_mode in expand_expr_addr_expr Richard Sandiford
2016-12-09 13:35 ` [58/67] Use scalar_int_mode in a try_combine optimisation Richard Sandiford
2016-12-09 13:36 ` [59/67] Add a rtx_jump_table_data::get_data_mode helper Richard Sandiford
2016-12-09 13:36 ` [60/67] Pass scalar_int_modes to do_jump_by_parts_* Richard Sandiford
2016-12-09 13:37 ` [61/67] Use scalar_int_mode in the AArch64 port Richard Sandiford
2016-12-09 13:38 ` [62/67] Big machine_mode to scalar_int_mode replacement Richard Sandiford
2016-12-09 13:38 ` [63/67] Simplifications after type switch Richard Sandiford
2016-12-09 13:40 ` [65/67] Use scalar_mode in the AArch64 port Richard Sandiford
2016-12-09 13:40 ` [66/67] Add a scalar_mode_pod class Richard Sandiford
2016-12-09 13:40 ` [64/67] Add a scalar_mode class Richard Sandiford
2016-12-09 13:41 ` [67/67] Add a complex_mode class Richard Sandiford
2016-12-09 18:20 ` [0/67] Add wrapper classes for machine_modes Sandra Loosemore
2017-05-05 7:08 ` Jeff Law
2017-05-24 14:33 ` Richard Sandiford
2017-06-28 17:27 ` Jeff Law
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87r35hntwv.fsf@e105548-lin.cambridge.arm.com \
--to=richard.sandiford@arm.com \
--cc=gcc-patches@gcc.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).