mirror of git://gcc.gnu.org/git/gcc.git
[6/77] Make GET_MODE_WIDER return an opt_mode
GET_MODE_WIDER previously returned VOIDmode if no wider mode existed. 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. 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_mode): New class. * machmode.h (opt_mode): Likewise. (opt_mode::else_void): New function. (opt_mode::require): 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): Update use of GET_MODE_2XWIDER_MODE, returning false if no such mode exists. * config/ia64/ia64.c (expand_vselect_vconcat): Likewise. * 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_2XWIDER_MODE. * omp-low.c (omp_clause_aligned_alignment): Likewise. * tree-ssa-math-opts.c (convert_mult_to_widen): Update use of GET_MODE_WIDER_MODE. (convert_plusminus_to_widen): 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. * gdbhooks.py (OptMachineModePrinter): New class. (build_pretty_printer): Use it for opt_mode. gcc/ada/ * gcc-interface/decl.c (validate_size): Update use of GET_MODE_WIDER_MODE, forcing a wider mode to exist. Co-Authored-By: Alan Hayward <alan.hayward@arm.com> Co-Authored-By: David Sherwood <david.sherwood@arm.com> From-SVN: r251457
This commit is contained in:
parent
ec35d57225
commit
490d0f6c91
|
|
@ -1,3 +1,63 @@
|
|||
2017-08-30 Richard Sandiford <richard.sandiford@linaro.org>
|
||||
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::require): 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): Update use of GET_MODE_2XWIDER_MODE,
|
||||
returning false if no such mode exists.
|
||||
* config/ia64/ia64.c (expand_vselect_vconcat): Likewise.
|
||||
* 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_2XWIDER_MODE.
|
||||
* omp-low.c (omp_clause_aligned_alignment): Likewise.
|
||||
* tree-ssa-math-opts.c (convert_mult_to_widen): Update use of
|
||||
GET_MODE_WIDER_MODE.
|
||||
(convert_plusminus_to_widen): 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.
|
||||
* gdbhooks.py (OptMachineModePrinter): New class.
|
||||
(build_pretty_printer): Use it for opt_mode.
|
||||
|
||||
2017-08-30 Richard Sandiford <richard.sandiford@linaro.org>
|
||||
Alan Hayward <alan.hayward@arm.com>
|
||||
David Sherwood <david.sherwood@arm.com>
|
||||
|
|
|
|||
|
|
@ -1,3 +1,10 @@
|
|||
2017-08-30 Richard Sandiford <richard.sandiford@linaro.org>
|
||||
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.
|
||||
|
||||
2017-08-30 Richard Sandiford <richard.sandiford@linaro.org>
|
||||
Alan Hayward <alan.hayward@arm.com>
|
||||
David Sherwood <david.sherwood@arm.com>
|
||||
|
|
|
|||
|
|
@ -8576,7 +8576,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).require ();
|
||||
type_size = bitsize_int (GET_MODE_BITSIZE (p_mode));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7604,10 +7604,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).require ();
|
||||
}
|
||||
|
||||
orig_pos = pos;
|
||||
|
|
|
|||
|
|
@ -6066,7 +6066,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).require ()
|
||||
&& 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))
|
||||
|
|
|
|||
|
|
@ -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).require ()) == 1)
|
||||
|
||||
#define HARD_REGNO_NREGS(REGNO, MODE) \
|
||||
((REGNO >= CR16_FIRST_DWORD_REGISTER) \
|
||||
|
|
|
|||
|
|
@ -28534,6 +28534,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;
|
||||
|
|
@ -28627,9 +28628,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.). */
|
||||
|
|
@ -43502,7 +43503,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).require ();
|
||||
gcc_assert (GET_MODE_NUNITS (o) == GET_MODE_NUNITS (n) * 2);
|
||||
gcc_assert (GET_MODE_SIZE (o) == GET_MODE_SIZE (n));
|
||||
return n;
|
||||
|
|
@ -46865,7 +46866,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;
|
||||
|
|
|
|||
|
|
@ -11298,7 +11298,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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21105,7 +21105,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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ typedef const struct simple_bitmap_def *const_sbitmap;
|
|||
struct rtx_def;
|
||||
typedef struct rtx_def *rtx;
|
||||
typedef const struct rtx_def *const_rtx;
|
||||
template<typename> class opt_mode;
|
||||
|
||||
/* Subclasses of rtx_def, using indentation to show the class
|
||||
hierarchy, along with the relevant invariant.
|
||||
|
|
|
|||
15
gcc/expmed.c
15
gcc/expmed.c
|
|
@ -207,11 +207,10 @@ init_expmed_one_mode (struct init_expmed_rtl *all,
|
|||
for (mode_from = MIN_MODE_INT; mode_from <= MAX_MODE_INT;
|
||||
mode_from = (machine_mode)(mode_from + 1))
|
||||
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);
|
||||
|
|
@ -3641,7 +3640,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).require ();
|
||||
op = expand_shift (RSHIFT_EXPR, wider_mode, op,
|
||||
GET_MODE_BITSIZE (mode), 0, 1);
|
||||
return convert_modes (mode, wider_mode, op, 0);
|
||||
|
|
@ -3663,7 +3662,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).require ();
|
||||
size = GET_MODE_BITSIZE (mode);
|
||||
|
||||
/* Firstly, try using a multiplication insn that only generates the needed
|
||||
|
|
@ -3769,7 +3768,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).require ();
|
||||
unsigned HOST_WIDE_INT cnst1;
|
||||
int extra_cost;
|
||||
bool sign_adjust = false;
|
||||
|
|
|
|||
|
|
@ -9159,7 +9159,7 @@ expand_expr_real_2 (sepops ops, rtx target, machine_mode tmode,
|
|||
if (code == LSHIFT_EXPR
|
||||
&& target
|
||||
&& REG_P (target)
|
||||
&& 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)
|
||||
|
|
|
|||
|
|
@ -422,6 +422,18 @@ class VecPrinter:
|
|||
|
||||
######################################################################
|
||||
|
||||
class OptMachineModePrinter:
|
||||
def __init__(self, gdbval):
|
||||
self.gdbval = gdbval
|
||||
|
||||
def to_string (self):
|
||||
name = str(self.gdbval['m_mode'])
|
||||
if name == 'E_VOIDmode':
|
||||
return '<None>'
|
||||
return name[2:] if name.startswith('E_') else name
|
||||
|
||||
######################################################################
|
||||
|
||||
# TODO:
|
||||
# * hashtab
|
||||
# * location_t
|
||||
|
|
@ -518,6 +530,9 @@ def build_pretty_printer():
|
|||
'vec',
|
||||
VecPrinter)
|
||||
|
||||
pp.add_printer_for_regex(r'opt_mode<(\S+)>',
|
||||
'opt_mode', OptMachineModePrinter)
|
||||
|
||||
return pp
|
||||
|
||||
gdb.printing.register_pretty_printer(
|
||||
|
|
|
|||
|
|
@ -1460,14 +1460,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);
|
||||
|
|
|
|||
|
|
@ -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).require ();
|
||||
|
||||
rtxes.target = gen_rtx_REG (word_mode, LAST_VIRTUAL_REGISTER + 1);
|
||||
rtxes.source = gen_rtx_REG (word_mode, LAST_VIRTUAL_REGISTER + 2);
|
||||
|
|
|
|||
|
|
@ -1636,7 +1636,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) (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
|
||||
|
|
|
|||
|
|
@ -221,6 +221,71 @@ 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. */
|
||||
template<typename T>
|
||||
class opt_mode
|
||||
{
|
||||
public:
|
||||
enum from_int { dummy = MAX_MACHINE_MODE };
|
||||
|
||||
ALWAYS_INLINE opt_mode () : m_mode (E_VOIDmode) {}
|
||||
ALWAYS_INLINE opt_mode (const T &m) : m_mode (m) {}
|
||||
ALWAYS_INLINE opt_mode (from_int m) : m_mode (machine_mode (m)) {}
|
||||
|
||||
machine_mode else_void () const;
|
||||
T require () const;
|
||||
|
||||
bool exists () const;
|
||||
template<typename U> bool exists (U *) const;
|
||||
|
||||
private:
|
||||
machine_mode m_mode;
|
||||
};
|
||||
|
||||
/* If the object contains a T, return its enum value, otherwise return
|
||||
E_VOIDmode. */
|
||||
|
||||
template<typename T>
|
||||
ALWAYS_INLINE machine_mode
|
||||
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>::require () const
|
||||
{
|
||||
gcc_checking_assert (m_mode != E_VOIDmode);
|
||||
return typename mode_traits<T>::from_int (m_mode);
|
||||
}
|
||||
|
||||
/* Return true if the object contains a T rather than nothing. */
|
||||
|
||||
template<typename T>
|
||||
ALWAYS_INLINE bool
|
||||
opt_mode<T>::exists () const
|
||||
{
|
||||
return m_mode != E_VOIDmode;
|
||||
}
|
||||
|
||||
/* 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 (typename mode_traits<T>::from_int (m_mode));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Return the base GET_MODE_SIZE value for MODE. */
|
||||
|
||||
ALWAYS_INLINE unsigned short
|
||||
|
|
@ -352,13 +417,22 @@ 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) mode_wider[MODE])
|
||||
template<typename T>
|
||||
ALWAYS_INLINE opt_mode<T>
|
||||
GET_MODE_WIDER_MODE (const T &m)
|
||||
{
|
||||
return typename opt_mode<T>::from_int (mode_wider[m]);
|
||||
}
|
||||
|
||||
/* 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) mode_2xwider[MODE])
|
||||
|
||||
template<typename T>
|
||||
ALWAYS_INLINE opt_mode<T>
|
||||
GET_MODE_2XWIDER_MODE (const T &m)
|
||||
{
|
||||
return typename opt_mode<T>::from_int (mode_2xwider[m]);
|
||||
}
|
||||
|
||||
/* Get the complex mode from the component mode. */
|
||||
extern const unsigned char mode_complex[NUM_MACHINE_MODES];
|
||||
|
|
@ -497,17 +571,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).require ();
|
||||
}
|
||||
|
||||
/* Set mode iterator *ITER to the mode that is two times wider than the
|
||||
|
|
@ -516,7 +590,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 ();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3456,8 +3456,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).require ();
|
||||
|
||||
tree type = lang_hooks.types.type_for_mode (mode, 1);
|
||||
if (type == NULL_TREE || TYPE_MODE (type) != mode)
|
||||
|
|
|
|||
|
|
@ -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).require ();
|
||||
buf[len + 1] = '0' + i;
|
||||
set_optab_libfunc (tab, mode, buf);
|
||||
mode = GET_MODE_2XWIDER_MODE (mode);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
20
gcc/optabs.c
20
gcc/optabs.c
|
|
@ -1186,13 +1186,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);
|
||||
|
||||
|
|
@ -1253,14 +1253,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;
|
||||
|
|
@ -3702,7 +3702,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);
|
||||
|
|
|
|||
|
|
@ -5671,13 +5671,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).require () == 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).require ();
|
||||
|
||||
if (targetm.mode_rep_extended (i, wider) == SIGN_EXTEND
|
||||
/* We can only check sign-bit copies starting from the
|
||||
|
|
|
|||
|
|
@ -2745,7 +2745,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);
|
||||
|
||||
|
|
@ -2782,7 +2783,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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3283,8 +3283,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;
|
||||
}
|
||||
|
||||
|
|
@ -3465,8 +3465,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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1088,8 +1088,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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10120,7 +10120,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
|
||||
|
|
@ -10129,15 +10129,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
|
||||
|
|
|
|||
|
|
@ -8706,12 +8706,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]))
|
||||
|
|
|
|||
Loading…
Reference in New Issue