From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 3543 invoked by alias); 5 Sep 2017 11:25:54 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 3530 invoked by uid 89); 5 Sep 2017 11:25:53 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-10.2 required=5.0 tests=AWL,BAYES_00,FREEMAIL_FROM,GIT_PATCH_2,GIT_PATCH_3,KAM_ASCII_DIVIDERS,RCVD_IN_DNSWL_NONE,SPF_PASS autolearn=ham version=3.3.2 spammy= X-HELO: mail-wm0-f48.google.com Received: from mail-wm0-f48.google.com (HELO mail-wm0-f48.google.com) (74.125.82.48) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 05 Sep 2017 11:25:47 +0000 Received: by mail-wm0-f48.google.com with SMTP id i145so17830448wmf.1 for ; Tue, 05 Sep 2017 04:25:46 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to; bh=H742Dti+OKi88qIFJ1+KBk0FnkhqwBREtmnjqJWEc+o=; b=l3VgvP6MFaPyLU9CsjES7C3bXUTccUKQUckc1VeGsCGOv5qMKuP/tw0ijnakaOtGAq cPHxPMNoWDY4Bm0xhNl0F3TNDHKtcIZIUqEjDlcOKHl8FHbo+cTTGsPVXQnmIV1J1C2J IRPLBc9cqzx81+zHQYe4OrNuGJ/Xt1tRUi5b/Hq1NUqhi1pblpFMlNCKq1tRLlcPe+H5 rli1pZbDbDJgnpiaW/R1grnoxGurIMX2XyXebMtNWEaTHCtJuRoJM+uC9PjBkuKDxDWo sHaw58cY0gW0g1Qhamt0cOUGJYFN9SyJAdCM/WpIWbMGV8OqmHMYL6+ZRgAbb3czfC/M +t+A== X-Gm-Message-State: AHPjjUge47We6pG8E2MUtCuVO7ZFk0hBirLGazXjmrUCNdm1170okTBo HiFXB3HA3afW+MYWFuMARmjV6Y1H0RZi X-Google-Smtp-Source: ADKCNb4Fp+spxiJviAOzBvtrjBFRiKIl8lLySIZrfL2rDoJgvK46tkl2/02gGZx98I5SJq7WlkcfJqOmma53aBFtMWo= X-Received: by 10.80.240.26 with SMTP id r26mr3052382edl.142.1504610744180; Tue, 05 Sep 2017 04:25:44 -0700 (PDT) MIME-Version: 1.0 Received: by 10.80.180.205 with HTTP; Tue, 5 Sep 2017 04:25:43 -0700 (PDT) In-Reply-To: <87d176itmx.fsf@linaro.org> References: <87tw0iiu51.fsf@linaro.org> <87d176itmx.fsf@linaro.org> From: Richard Biener Date: Tue, 05 Sep 2017 11:25:00 -0000 Message-ID: Subject: Re: [4/9] Make mode_for_size return an opt_mode To: GCC Patches , Richard Sandiford Content-Type: text/plain; charset="UTF-8" X-IsSubscribed: yes X-SW-Source: 2017-09/txt/msg00253.txt.bz2 On Mon, Sep 4, 2017 at 1:35 PM, Richard Sandiford wrote: > ...to make it consistent with int_mode_for_size etc. > > require () seems like the right choice in replace_reg_with_saved_mem > because we use the chosen mode for saving and restoring registers, > which cannot be done in BLKmode. Similarly require () seems like > the right choice in calls related to secondary memory reloads (the ones > in config/, and in get_secondary_mem) because the reload must always > have a defined mode, which e.g. determines the size of the slot. > > We can use require () in simplify_subreg_concatn and assemble_integer > because it isn't meaningful to create a subreg with BLKmode (for one > thing, we couldn't tell then whether it was partial, paradoxical, etc.). > > make_fract_type and make_accum_type must find a mode because that's > what distinguishes accumulator FIXED_POINT_TYPEs from fractional > FIXED_POINT_TYPEs. Ok. Richard. > 2017-09-04 Richard Sandiford > > gcc/ > * machmode.h (opt_machine_mode): New type. > (opt_mode): Allow construction from anything that can be > converted to a T. > (is_a, as_a, dyn_cast): Add overloads for opt_mode. > (mode_for_size): Return an opt_machine_mode. > * stor-layout.c (mode_for_size): Likewise. > (mode_for_size_tree): Update call accordingly. > (bitwise_mode_for_mode): Likewise. > (make_fract_type): Likewise. > (make_accum_type): Likewise. > * caller-save.c (replace_reg_with_saved_mem): Update call > accordingly. > * config/alpha/alpha.h (SECONDARY_MEMORY_NEEDED_MODE): Likewise. > * config/i386/i386.h (SECONDARY_MEMORY_NEEDED_MODE): Likewise. > * config/s390/s390.h (SECONDARY_MEMORY_NEEDED_MODE): Likewise. > * config/sparc/sparc.h (SECONDARY_MEMORY_NEEDED_MODE): Likewise. > * expmed.c (extract_bit_field_1): Likewise. > * reload.c (get_secondary_mem): Likewise. > * varasm.c (assemble_integer): Likewise. > * lower-subreg.c (simplify_subreg_concatn): Likewise. Move > early-out. > > Index: gcc/machmode.h > =================================================================== > --- gcc/machmode.h 2017-09-04 12:18:47.820398622 +0100 > +++ gcc/machmode.h 2017-09-04 12:18:50.674859598 +0100 > @@ -20,6 +20,8 @@ Software Foundation; either version 3, o > #ifndef HAVE_MACHINE_MODES > #define HAVE_MACHINE_MODES > > +typedef opt_mode opt_machine_mode; > + > extern CONST_MODE_SIZE unsigned short mode_size[NUM_MACHINE_MODES]; > extern const unsigned short mode_precision[NUM_MACHINE_MODES]; > extern const unsigned char mode_inner[NUM_MACHINE_MODES]; > @@ -237,6 +239,8 @@ #define POINTER_BOUNDS_MODE_P(MODE) > > ALWAYS_INLINE opt_mode () : m_mode (E_VOIDmode) {} > ALWAYS_INLINE opt_mode (const T &m) : m_mode (m) {} > + template > + ALWAYS_INLINE opt_mode (const U &m) : m_mode (T (m)) {} > ALWAYS_INLINE opt_mode (from_int m) : m_mode (machine_mode (m)) {} > > machine_mode else_void () const; > @@ -325,6 +329,13 @@ is_a (machine_mode m) > return T::includes_p (m); > } > > +template > +inline bool > +is_a (const opt_mode &m) > +{ > + return T::includes_p (m.else_void ()); > +} > + > /* Assert that mode M has type T, and return it in that form. */ > > template > @@ -335,6 +346,13 @@ as_a (machine_mode m) > return typename mode_traits::from_int (m); > } > > +template > +inline T > +as_a (const opt_mode &m) > +{ > + return as_a (m.else_void ()); > +} > + > /* Convert M to an opt_mode. */ > > template > @@ -346,6 +364,13 @@ dyn_cast (machine_mode m) > return opt_mode (); > } > > +template > +inline opt_mode > +dyn_cast (const opt_mode &m) > +{ > + return dyn_cast (m.else_void ()); > +} > + > /* Return true if mode M has type T, storing it as a T in *RESULT > if so. */ > > @@ -627,11 +652,7 @@ GET_MODE_2XWIDER_MODE (const T &m) > extern const unsigned char mode_complex[NUM_MACHINE_MODES]; > #define GET_MODE_COMPLEX_MODE(MODE) ((machine_mode) mode_complex[MODE]) > > -/* Return the mode for data of a given size SIZE and mode class CLASS. > - If LIMIT is nonzero, then don't use modes bigger than MAX_FIXED_MODE_SIZE. > - The value is BLKmode if no other mode is found. */ > - > -extern machine_mode mode_for_size (unsigned int, enum mode_class, int); > +extern opt_machine_mode mode_for_size (unsigned int, enum mode_class, int); > > /* Return the machine mode to use for a MODE_INT of SIZE bits, if one > exists. If LIMIT is nonzero, modes wider than MAX_FIXED_MODE_SIZE > Index: gcc/stor-layout.c > =================================================================== > --- gcc/stor-layout.c 2017-09-04 12:18:44.944553324 +0100 > +++ gcc/stor-layout.c 2017-09-04 12:18:50.675762071 +0100 > @@ -291,19 +291,19 @@ finalize_size_functions (void) > vec_free (size_functions); > } > > -/* Return the machine mode to use for a nonscalar of SIZE bits. The > - mode must be in class MCLASS, and have exactly that many value bits; > - it may have padding as well. If LIMIT is nonzero, modes of wider > - than MAX_FIXED_MODE_SIZE will not be used. */ > +/* Return a machine mode of class MCLASS with SIZE bits of precision, > + if one exists. The mode may have padding bits as well the SIZE > + value bits. If LIMIT is nonzero, disregard modes wider than > + MAX_FIXED_MODE_SIZE. */ > > -machine_mode > +opt_machine_mode > mode_for_size (unsigned int size, enum mode_class mclass, int limit) > { > machine_mode mode; > int i; > > if (limit && size > MAX_FIXED_MODE_SIZE) > - return BLKmode; > + return opt_machine_mode (); > > /* Get the first mode which has this size, in the specified class. */ > FOR_EACH_MODE_IN_CLASS (mode, mclass) > @@ -316,7 +316,7 @@ mode_for_size (unsigned int size, enum m > && int_n_enabled_p[i]) > return int_n_data[i].m; > > - return BLKmode; > + return opt_machine_mode (); > } > > /* Similar, except passed a tree node. */ > @@ -333,11 +333,11 @@ mode_for_size_tree (const_tree size, enu > ui = uhwi; > if (uhwi != ui) > return BLKmode; > - return mode_for_size (ui, mclass, limit); > + return mode_for_size (ui, mclass, limit).else_blk (); > } > > -/* Similar, but never return BLKmode; return the narrowest mode that > - contains at least the requested number of value bits. */ > +/* Return the narrowest mode of class MCLASS that contains at least > + SIZE bits. Abort if no such mode exists. */ > > machine_mode > smallest_mode_for_size (unsigned int size, enum mode_class mclass) > @@ -426,9 +426,8 @@ bitwise_mode_for_mode (machine_mode mode > if (COMPLEX_MODE_P (mode)) > { > machine_mode trial = mode; > - if (GET_MODE_CLASS (mode) != MODE_COMPLEX_INT) > - trial = mode_for_size (bitsize, MODE_COMPLEX_INT, false); > - if (trial != BLKmode > + if ((GET_MODE_CLASS (trial) == MODE_COMPLEX_INT > + || mode_for_size (bitsize, MODE_COMPLEX_INT, false).exists (&trial)) > && have_regs_of_mode[GET_MODE_INNER (trial)]) > return trial; > } > @@ -438,16 +437,15 @@ bitwise_mode_for_mode (machine_mode mode > if (VECTOR_MODE_P (mode) || bitsize > MAX_FIXED_MODE_SIZE) > { > machine_mode trial = mode; > - if (GET_MODE_CLASS (mode) != MODE_VECTOR_INT) > - trial = mode_for_size (bitsize, MODE_VECTOR_INT, 0); > - if (trial != BLKmode > + if ((GET_MODE_CLASS (trial) == MODE_VECTOR_INT > + || mode_for_size (bitsize, MODE_VECTOR_INT, 0).exists (&trial)) > && have_regs_of_mode[trial] > && targetm.vector_mode_supported_p (trial)) > return trial; > } > > /* Otherwise fall back on integers while honoring MAX_FIXED_MODE_SIZE. */ > - return mode_for_size (bitsize, MODE_INT, true); > + return mode_for_size (bitsize, MODE_INT, true).else_blk (); > } > > /* Find a type that can be used for efficient bitwise operations on MODE. > @@ -2543,13 +2541,9 @@ make_fract_type (int precision, int unsi > TYPE_SATURATING (type) = 1; > > /* Lay out the type: set its alignment, size, etc. */ > - if (unsignedp) > - { > - TYPE_UNSIGNED (type) = 1; > - SET_TYPE_MODE (type, mode_for_size (precision, MODE_UFRACT, 0)); > - } > - else > - SET_TYPE_MODE (type, mode_for_size (precision, MODE_FRACT, 0)); > + TYPE_UNSIGNED (type) = unsignedp; > + enum mode_class mclass = unsignedp ? MODE_UFRACT : MODE_FRACT; > + SET_TYPE_MODE (type, mode_for_size (precision, mclass, 0).require ()); > layout_type (type); > > return type; > @@ -2569,13 +2563,9 @@ make_accum_type (int precision, int unsi > TYPE_SATURATING (type) = 1; > > /* Lay out the type: set its alignment, size, etc. */ > - if (unsignedp) > - { > - TYPE_UNSIGNED (type) = 1; > - SET_TYPE_MODE (type, mode_for_size (precision, MODE_UACCUM, 0)); > - } > - else > - SET_TYPE_MODE (type, mode_for_size (precision, MODE_ACCUM, 0)); > + TYPE_UNSIGNED (type) = unsignedp; > + enum mode_class mclass = unsignedp ? MODE_UACCUM : MODE_ACCUM; > + SET_TYPE_MODE (type, mode_for_size (precision, mclass, 0).require ()); > layout_type (type); > > return type; > Index: gcc/caller-save.c > =================================================================== > --- gcc/caller-save.c 2017-09-04 11:49:42.884500727 +0100 > +++ gcc/caller-save.c 2017-09-04 12:18:50.672152181 +0100 > @@ -1161,7 +1161,7 @@ replace_reg_with_saved_mem (rtx *loc, > gcc_assert (smode != VOIDmode); > if (hard_regno_nregs [regno][smode] > 1) > smode = mode_for_size (GET_MODE_SIZE (mode) / nregs, > - GET_MODE_CLASS (mode), 0); > + GET_MODE_CLASS (mode), 0).require (); > XVECEXP (mem, 0, i) = gen_rtx_REG (smode, regno + i); > } > } > Index: gcc/config/alpha/alpha.h > =================================================================== > --- gcc/config/alpha/alpha.h 2017-09-04 11:50:08.504926375 +0100 > +++ gcc/config/alpha/alpha.h 2017-09-04 12:18:50.672152181 +0100 > @@ -508,7 +508,7 @@ #define SECONDARY_MEMORY_NEEDED(CLASS1,C > #define SECONDARY_MEMORY_NEEDED_MODE(MODE) \ > (GET_MODE_CLASS (MODE) == MODE_FLOAT ? (MODE) \ > : GET_MODE_SIZE (MODE) >= 4 ? (MODE) \ > - : mode_for_size (BITS_PER_WORD, GET_MODE_CLASS (MODE), 0)) > + : mode_for_size (BITS_PER_WORD, GET_MODE_CLASS (MODE), 0).require ()) > > /* Return the class of registers that cannot change mode from FROM to TO. */ > > Index: gcc/config/i386/i386.h > =================================================================== > --- gcc/config/i386/i386.h 2017-09-04 11:50:08.515731048 +0100 > +++ gcc/config/i386/i386.h 2017-09-04 12:18:50.672152181 +0100 > @@ -1548,7 +1548,7 @@ #define SECONDARY_MEMORY_NEEDED(CLASS1, > for integral modes that can be moved using 32 bit move. */ > #define SECONDARY_MEMORY_NEEDED_MODE(MODE) \ > (GET_MODE_BITSIZE (MODE) < 32 && INTEGRAL_MODE_P (MODE) \ > - ? mode_for_size (32, GET_MODE_CLASS (MODE), 0) \ > + ? mode_for_size (32, GET_MODE_CLASS (MODE), 0).require () \ > : MODE) > > /* Return a class of registers that cannot change FROM mode to TO mode. */ > Index: gcc/config/s390/s390.h > =================================================================== > --- gcc/config/s390/s390.h 2017-09-04 11:50:24.561571751 +0100 > +++ gcc/config/s390/s390.h 2017-09-04 12:18:50.673054653 +0100 > @@ -624,9 +624,9 @@ #define SECONDARY_MEMORY_NEEDED(CLASS1, > > /* Get_secondary_mem widens its argument to BITS_PER_WORD which loses on 64bit > because the movsi and movsf patterns don't handle r/f moves. */ > -#define SECONDARY_MEMORY_NEEDED_MODE(MODE) \ > - (GET_MODE_BITSIZE (MODE) < 32 \ > - ? mode_for_size (32, GET_MODE_CLASS (MODE), 0) \ > +#define SECONDARY_MEMORY_NEEDED_MODE(MODE) \ > + (GET_MODE_BITSIZE (MODE) < 32 \ > + ? mode_for_size (32, GET_MODE_CLASS (MODE), 0).require () \ > : (MODE)) > > > Index: gcc/config/sparc/sparc.h > =================================================================== > --- gcc/config/sparc/sparc.h 2017-09-04 11:50:24.563372530 +0100 > +++ gcc/config/sparc/sparc.h 2017-09-04 12:18:50.673054653 +0100 > @@ -1077,13 +1077,13 @@ #define SECONDARY_MEMORY_NEEDED(CLASS1, > /* Get_secondary_mem widens its argument to BITS_PER_WORD which loses on v9 > because the movsi and movsf patterns don't handle r/f moves. > For v8 we copy the default definition. */ > -#define SECONDARY_MEMORY_NEEDED_MODE(MODE) \ > - (TARGET_ARCH64 \ > - ? (GET_MODE_BITSIZE (MODE) < 32 \ > - ? mode_for_size (32, GET_MODE_CLASS (MODE), 0) \ > - : MODE) \ > - : (GET_MODE_BITSIZE (MODE) < BITS_PER_WORD \ > - ? mode_for_size (BITS_PER_WORD, GET_MODE_CLASS (MODE), 0) \ > +#define SECONDARY_MEMORY_NEEDED_MODE(MODE) \ > + (TARGET_ARCH64 \ > + ? (GET_MODE_BITSIZE (MODE) < 32 \ > + ? mode_for_size (32, GET_MODE_CLASS (MODE), 0).require () \ > + : MODE) \ > + : (GET_MODE_BITSIZE (MODE) < BITS_PER_WORD \ > + ? mode_for_size (BITS_PER_WORD, GET_MODE_CLASS (MODE), 0).require () \ > : MODE)) > > /* Return the maximum number of consecutive registers > Index: gcc/expmed.c > =================================================================== > --- gcc/expmed.c 2017-09-04 11:50:08.544543511 +0100 > +++ gcc/expmed.c 2017-09-04 12:18:50.673054653 +0100 > @@ -1711,14 +1711,9 @@ extract_bit_field_1 (rtx str_rtx, unsign > > /* Get the mode of the field to use for atomic access or subreg > conversion. */ > - mode1 = mode; > - if (SCALAR_INT_MODE_P (tmode)) > - { > - machine_mode try_mode = mode_for_size (bitsize, > - GET_MODE_CLASS (tmode), 0); > - if (try_mode != BLKmode) > - mode1 = try_mode; > - } > + if (!SCALAR_INT_MODE_P (tmode) > + || !mode_for_size (bitsize, GET_MODE_CLASS (tmode), 0).exists (&mode1)) > + mode1 = mode; > gcc_assert (mode1 != BLKmode); > > /* Extraction of a full MODE1 value can be done with a subreg as long > Index: gcc/reload.c > =================================================================== > --- gcc/reload.c 2017-09-04 11:49:42.941500722 +0100 > +++ gcc/reload.c 2017-09-04 12:18:50.675762071 +0100 > @@ -578,7 +578,8 @@ get_secondary_mem (rtx x ATTRIBUTE_UNUSE > mode = SECONDARY_MEMORY_NEEDED_MODE (mode); > #else > if (GET_MODE_BITSIZE (mode) < BITS_PER_WORD && INTEGRAL_MODE_P (mode)) > - mode = mode_for_size (BITS_PER_WORD, GET_MODE_CLASS (mode), 0); > + mode = mode_for_size (BITS_PER_WORD, > + GET_MODE_CLASS (mode), 0).require (); > #endif > > /* If we already have made a MEM for this operand in MODE, return it. */ > Index: gcc/varasm.c > =================================================================== > --- gcc/varasm.c 2017-09-04 11:49:42.944500722 +0100 > +++ gcc/varasm.c 2017-09-04 12:18:50.676664544 +0100 > @@ -2780,8 +2780,8 @@ assemble_integer (rtx x, unsigned int si > else > mclass = MODE_INT; > > - omode = mode_for_size (subsize * BITS_PER_UNIT, mclass, 0); > - imode = mode_for_size (size * BITS_PER_UNIT, mclass, 0); > + omode = mode_for_size (subsize * BITS_PER_UNIT, mclass, 0).require (); > + imode = mode_for_size (size * BITS_PER_UNIT, mclass, 0).require (); > > for (i = 0; i < size; i += subsize) > { > Index: gcc/lower-subreg.c > =================================================================== > --- gcc/lower-subreg.c 2017-09-04 12:18:41.572976650 +0100 > +++ gcc/lower-subreg.c 2017-09-04 12:18:50.674859598 +0100 > @@ -616,20 +616,18 @@ simplify_subreg_concatn (machine_mode ou > part = XVECEXP (op, 0, byte / inner_size); > partmode = GET_MODE (part); > > + final_offset = byte % inner_size; > + if (final_offset + GET_MODE_SIZE (outermode) > inner_size) > + return NULL_RTX; > + > /* VECTOR_CSTs in debug expressions are expanded into CONCATN instead of > regular CONST_VECTORs. They have vector or integer modes, depending > on the capabilities of the target. Cope with them. */ > if (partmode == VOIDmode && VECTOR_MODE_P (innermode)) > partmode = GET_MODE_INNER (innermode); > else if (partmode == VOIDmode) > - { > - enum mode_class mclass = GET_MODE_CLASS (innermode); > - partmode = mode_for_size (inner_size * BITS_PER_UNIT, mclass, 0); > - } > - > - final_offset = byte % inner_size; > - if (final_offset + GET_MODE_SIZE (outermode) > inner_size) > - return NULL_RTX; > + partmode = mode_for_size (inner_size * BITS_PER_UNIT, > + GET_MODE_CLASS (innermode), 0).require (); > > return simplify_gen_subreg (outermode, part, partmode, final_offset); > }