From patchwork Thu Jul 13 08:40:04 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 107592 Delivered-To: patch@linaro.org Received: by 10.140.101.44 with SMTP id t41csp1924824qge; Thu, 13 Jul 2017 01:40:33 -0700 (PDT) X-Received: by 10.84.217.22 with SMTP id o22mr9012809pli.19.1499935233222; Thu, 13 Jul 2017 01:40:33 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1499935233; cv=none; d=google.com; s=arc-20160816; b=LfRsZ+/3LzKNXhoG3HSmdo8wFrIz+w+ApG73sAmytnTCYe0I5ABrQ/eIlqDdcNcKDE og7kGPRZqPGdBTfQl35M4jSaMN4fAczy6XFIUu4i+kqO3slfMqkNQ67oBYbTW6c7BSms BpdqaJj9X6oNs3979dM0mzo5JbWVUJAD0nkpnhuMgW1T7GgsqWMHNS9DYyUIIh6N7YA2 g8bDFtYzLFR6j7yqHY4PS1wCk+hX/0b763xDqRJsKNk5XpuvxEKjusEpst/2VyXSH1Pu BcEKuRkxuYq9FxnlS8eWz/L+UQKFjxS2jcFU3ZoEbzacpImrH4KfRi/TmWUSlgeRZk7u 1yPw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=mime-version:user-agent:message-id:in-reply-to:date:references :subject:mail-followup-to:to:from:delivered-to:sender:list-help :list-post:list-archive:list-unsubscribe:list-id:precedence :mailing-list:dkim-signature:domainkey-signature :arc-authentication-results; bh=xpBnUOoGUOiduIJQyTDpbim6y/JWTWgZ9A6Owvd3PnU=; b=D3oDZwBM+QycvSxxYg9rIk87gX+lY/9RTHyazxRk3qjaotAJ8uPgXFU62wMDgYDlgB QaOsHI0m9rWpwJ7WiplJSLxNRFzcQQ1zBe2/51FvBhDGlXSXQNl+5AMl7vvT1SW3lxmX d+4tkBKb0U9+pB8IZhCJXfpcztukcKeoM+cE7doBsrc5oM2Oj3YER/EM/KMfbGzpvghV BXuotxR0JMu1N2eTNP96YMJePHGcnwJHHNoRYr3EA6hYscAt5X+v7xsvk/OKsQXPlus1 MwJVBcIMsjWlR3eVPgGOdzdFpaXQfRdgEUP8myQu672ZiU46TZzguJJkY9o3oeJPt7cO kojA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.b=j0bfj7S+; spf=pass (google.com: domain of gcc-patches-return-457996-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-457996-patch=linaro.org@gcc.gnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id e13si3839596pgu.2.2017.07.13.01.40.32 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 13 Jul 2017 01:40:33 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-return-457996-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.b=j0bfj7S+; spf=pass (google.com: domain of gcc-patches-return-457996-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-457996-patch=linaro.org@gcc.gnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:references:date:in-reply-to:message-id:mime-version :content-type; q=dns; s=default; b=VP+lBGJm1rI7o9ODNBuPXj7If2hke 4jC0WupgRB1KXhhHZ/uOrbzv937bZ3NBCChLVo5zZjLQfdWqn5uEZOLjrrMMr2ZX Fo9wYKf1PC0fc8QqgEkLN85qj7lsDttU+pZqScjqpT59dh90WR/yt2DL5+YuDQ5b X6paVkcFLkUsRA= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:references:date:in-reply-to:message-id:mime-version :content-type; s=default; bh=gOC0YY6ZCfv6gZ4/DshpT+UX3Ck=; b=j0b fj7S+K6hoFOUBZIu9oZ3naRm+7w9tjnTUiTYy/qch3vB5ZM8cqgttLhu/Me2Wcya meuu9F/wF49ysoUbRwhnt6CvstJ4OQdHLcy/At/qkAHkIlPGo2awuRni6SNhD2MR ezLD/n+En7e7oQDS57QfV7jaX5bs2x6HaRvKGZsA= Received: (qmail 14871 invoked by alias); 13 Jul 2017 08:40:15 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 14194 invoked by uid 89); 13 Jul 2017 08:40:15 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-11.0 required=5.0 tests=AWL, BAYES_00, 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; Thu, 13 Jul 2017 08:40:10 +0000 Received: by mail-wm0-f48.google.com with SMTP id t70so2145061wmt.0 for ; Thu, 13 Jul 2017 01:40:09 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:mail-followup-to:subject:references:date :in-reply-to:message-id:user-agent:mime-version; bh=xpBnUOoGUOiduIJQyTDpbim6y/JWTWgZ9A6Owvd3PnU=; b=UM2e5DgOucOI1S0Iev1iavHlY1U6fbo7TJVsb3EQXR04zlDvZqkglZgivLhSTBPwa+ t4HolbpNP4Ypt2HQ2qGJG5D6zDGqoMU6Hk34/GZY9sl0I3faIFarLp+7FDP861xZ7mZI fiwsU3GwCOgNEdM/vb6OfuH6/dT8x/Sbsawy/C5B0Mg3C/luR6/yu9tYL2HlW2+VqE0v 07iRjV3aLSL/dqdj/St/iSLpG0ti4OeUuHHoIj96deO5ezS8fPn2hsqTYoGvBi4T/jAT rPaAyHWg6yb0iwZgEWdzc4gL0LAikS8g+20hqlYDeO3L+5vLStBeT0Z51ybYgu2V9k58 zQzQ== X-Gm-Message-State: AIVw113riSfLVRBqH9A0rraF8Uh4Xlx0FS3ZWVLOfeK3QEWUpRd5Hds9 xwcSR5Bm9ED4Fhziv06rJA== X-Received: by 10.28.194.137 with SMTP id s131mr1073585wmf.111.1499935206995; Thu, 13 Jul 2017 01:40:06 -0700 (PDT) Received: from localhost (92.40.249.184.threembb.co.uk. [92.40.249.184]) by smtp.gmail.com with ESMTPSA id i22sm4339389wrb.30.2017.07.13.01.40.05 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 13 Jul 2017 01:40:06 -0700 (PDT) From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, richard.sandiford@linaro.org Subject: [06/77] Make GET_MODE_WIDER return an opt_mode References: <8760ewohsv.fsf@linaro.org> Date: Thu, 13 Jul 2017 09:40:04 +0100 In-Reply-To: <8760ewohsv.fsf@linaro.org> (Richard Sandiford's message of "Thu, 13 Jul 2017 09:35:44 +0100") Message-ID: <87fue0n317.fsf@linaro.org> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.2 (gnu/linux) MIME-Version: 1.0 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 class, which holds either a T or nothing. 2017-07-13 Richard Sandiford Alan Hayward David Sherwood gcc/ * 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): 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. Index: gcc/coretypes.h =================================================================== --- gcc/coretypes.h 2017-07-02 10:05:20.995639436 +0100 +++ gcc/coretypes.h 2017-07-13 09:18:22.924279021 +0100 @@ -55,6 +55,7 @@ typedef const struct simple_bitmap_def * struct rtx_def; typedef struct rtx_def *rtx; typedef const struct rtx_def *const_rtx; +template class opt_mode; /* Subclasses of rtx_def, using indentation to show the class hierarchy, along with the relevant invariant. Index: gcc/machmode.h =================================================================== --- gcc/machmode.h 2017-07-13 09:18:21.533429040 +0100 +++ gcc/machmode.h 2017-07-13 09:18:22.930278376 +0100 @@ -221,6 +221,72 @@ #define CLASS_HAS_WIDER_MODES_P(CLASS) #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 +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 operator * () const; + + bool exists () const; + template bool exists (U *) const; + +private: + machine_mode m_mode; +}; + +/* If the object contains a T, return its enum value, otherwise return + E_VOIDmode. */ + +template +ALWAYS_INLINE machine_mode +opt_mode::else_void () const +{ + return m_mode; +} + +/* Assert that the object contains a T and return it. */ + +template +inline T +opt_mode::operator * () const +{ + gcc_checking_assert (m_mode != E_VOIDmode); + return typename mode_traits::from_int (m_mode); +} + +/* Return true if the object contains a T rather than nothing. */ + +template +ALWAYS_INLINE bool +opt_mode::exists () const +{ + return m_mode != E_VOIDmode; +} + +/* Return true if the object contains a T, storing it in *MODE if so. */ + +template +template +inline bool +opt_mode::exists (U *mode) const +{ + if (m_mode != E_VOIDmode) + { + *mode = T (typename mode_traits::from_int (m_mode)); + return true; + } + return false; +} + /* Return the base GET_MODE_SIZE value for MODE. */ ALWAYS_INLINE unsigned short @@ -352,13 +418,22 @@ #define GET_MODE_NUNITS(MODE) (mode_to_n /* 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 +ALWAYS_INLINE opt_mode +GET_MODE_WIDER_MODE (const T &m) +{ + return typename opt_mode::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 +ALWAYS_INLINE opt_mode +GET_MODE_2XWIDER_MODE (const T &m) +{ + return typename opt_mode::from_int (mode_2xwider[m]); +} /* Get the complex mode from the component mode. */ extern const unsigned char mode_complex[NUM_MACHINE_MODES]; @@ -497,17 +572,17 @@ struct int_n_data_t { 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 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 @@ -516,7 +591,7 @@ struct int_n_data_t { inline void get_2xwider (machine_mode *iter) { - *iter = GET_MODE_2XWIDER_MODE (*iter); + *iter = GET_MODE_2XWIDER_MODE (*iter).else_void (); } } Index: gcc/combine.c =================================================================== --- gcc/combine.c 2017-07-13 09:18:21.524430018 +0100 +++ gcc/combine.c 2017-07-13 09:18:22.914280096 +0100 @@ -7617,10 +7617,7 @@ make_extraction (machine_mode mode, rtx 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; Index: gcc/config/cr16/cr16.h =================================================================== --- gcc/config/cr16/cr16.h 2017-04-18 19:52:36.663792154 +0100 +++ gcc/config/cr16/cr16.h 2017-07-13 09:18:22.915279989 +0100 @@ -197,9 +197,7 @@ #define CALL_USED_REGISTERS /* 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) \ Index: gcc/rtlanal.c =================================================================== --- gcc/rtlanal.c 2017-07-13 09:18:21.536428715 +0100 +++ gcc/rtlanal.c 2017-07-13 09:18:22.937277624 +0100 @@ -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) == 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 Index: gcc/config/c6x/c6x.c =================================================================== --- gcc/config/c6x/c6x.c 2017-07-13 09:18:19.037703403 +0100 +++ gcc/config/c6x/c6x.c 2017-07-13 09:18:22.915279989 +0100 @@ -6065,7 +6065,7 @@ c6x_rtx_costs (rtx x, machine_mode mode, /* 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)) Index: gcc/lower-subreg.c =================================================================== --- gcc/lower-subreg.c 2017-05-18 07:51:11.882801135 +0100 +++ gcc/lower-subreg.c 2017-07-13 09:18:22.929278484 +0100 @@ -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); Index: gcc/optabs-libfuncs.c =================================================================== --- gcc/optabs-libfuncs.c 2017-02-23 19:54:04.000000000 +0000 +++ gcc/optabs-libfuncs.c 2017-07-13 09:18:22.933278054 +0100 @@ -918,9 +918,10 @@ init_sync_libfuncs_1 (optab tab, const c 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); } } Index: gcc/config/i386/i386.c =================================================================== --- gcc/config/i386/i386.c 2017-07-13 09:18:21.528429583 +0100 +++ gcc/config/i386/i386.c 2017-07-13 09:18:22.921279344 +0100 @@ -28388,6 +28388,7 @@ ix86_expand_set_or_movmem (rtx dst, rtx 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; @@ -28481,9 +28482,9 @@ ix86_expand_set_or_movmem (rtx dst, rtx 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.). */ @@ -43337,7 +43338,7 @@ static bool expand_vec_perm_palignr (str 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; @@ -46605,7 +46606,8 @@ expand_vselect_vconcat (rtx target, rtx 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; Index: gcc/config/ia64/ia64.c =================================================================== --- gcc/config/ia64/ia64.c 2017-07-13 09:18:19.067700078 +0100 +++ gcc/config/ia64/ia64.c 2017-07-13 09:18:22.922279236 +0100 @@ -11297,7 +11297,8 @@ expand_vselect_vconcat (rtx target, rtx 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); } Index: gcc/config/mips/mips.c =================================================================== --- gcc/config/mips/mips.c 2017-07-13 09:18:19.076699080 +0100 +++ gcc/config/mips/mips.c 2017-07-13 09:18:22.924279021 +0100 @@ -21105,7 +21105,8 @@ mips_expand_vselect_vconcat (rtx target, 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); } Index: gcc/expmed.c =================================================================== --- gcc/expmed.c 2017-07-13 09:18:21.531429258 +0100 +++ gcc/expmed.c 2017-07-13 09:18:22.925278914 +0100 @@ -206,11 +206,10 @@ init_expmed_one_mode (struct init_expmed { 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); @@ -3588,7 +3587,7 @@ extract_high_half (machine_mode mode, rt 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); @@ -3610,7 +3609,7 @@ expmed_mult_highpart_optab (machine_mode 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 @@ -3716,7 +3715,7 @@ expmed_mult_highpart_optab (machine_mode 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; Index: gcc/expr.c =================================================================== --- gcc/expr.c 2017-07-13 09:18:21.532429149 +0100 +++ gcc/expr.c 2017-07-13 09:18:22.928278591 +0100 @@ -9153,7 +9153,7 @@ #define REDUCE_BIT_FIELD(expr) (reduce_b 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) Index: gcc/lto-streamer-in.c =================================================================== --- gcc/lto-streamer-in.c 2017-06-30 12:50:38.331658620 +0100 +++ gcc/lto-streamer-in.c 2017-07-13 09:18:22.930278376 +0100 @@ -1593,7 +1593,7 @@ lto_input_mode_table (struct lto_file_de : 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 Index: gcc/optabs-query.c =================================================================== --- gcc/optabs-query.c 2017-07-13 09:18:21.534428932 +0100 +++ gcc/optabs-query.c 2017-07-13 09:18:22.934277946 +0100 @@ -425,7 +425,7 @@ find_widening_optab_handler_and_mode (op 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); Index: gcc/stor-layout.c =================================================================== --- gcc/stor-layout.c 2017-07-13 09:18:21.536428715 +0100 +++ gcc/stor-layout.c 2017-07-13 09:18:22.938277517 +0100 @@ -2719,7 +2719,8 @@ fixup_unsigned_type (tree type) 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); @@ -2756,7 +2757,7 @@ bit_field_mode_iterator::next_mode (mach 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; } Index: gcc/internal-fn.c =================================================================== --- gcc/internal-fn.c 2017-07-08 11:37:46.037390715 +0100 +++ gcc/internal-fn.c 2017-07-13 09:18:22.929278484 +0100 @@ -1446,14 +1446,14 @@ expand_mul_overflow (location_t loc, tre 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); Index: gcc/omp-low.c =================================================================== --- gcc/omp-low.c 2017-07-13 09:18:21.533429040 +0100 +++ gcc/omp-low.c 2017-07-13 09:18:22.933278054 +0100 @@ -3452,8 +3452,8 @@ omp_clause_aligned_alignment (tree claus 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) Index: gcc/tree-ssa-math-opts.c =================================================================== --- gcc/tree-ssa-math-opts.c 2017-07-13 09:18:21.537428606 +0100 +++ gcc/tree-ssa-math-opts.c 2017-07-13 09:18:22.939277409 +0100 @@ -3160,8 +3160,8 @@ convert_mult_to_widen (gimple *stmt, gim || (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_ || (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; } Index: gcc/tree-switch-conversion.c =================================================================== --- gcc/tree-switch-conversion.c 2017-07-13 09:18:22.307345334 +0100 +++ gcc/tree-switch-conversion.c 2017-07-13 09:18:22.939277409 +0100 @@ -1085,8 +1085,7 @@ array_value_type (gswitch *swtch, tree t 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; } Index: gcc/var-tracking.c =================================================================== --- gcc/var-tracking.c 2017-07-13 09:18:21.539428389 +0100 +++ gcc/var-tracking.c 2017-07-13 09:18:22.945276764 +0100 @@ -8706,12 +8706,11 @@ emit_note_insn_var_location (variable ** 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])) Index: gcc/tree-vrp.c =================================================================== --- gcc/tree-vrp.c 2017-07-05 16:25:08.469709143 +0100 +++ gcc/tree-vrp.c 2017-07-13 09:18:22.943276979 +0100 @@ -10115,7 +10115,7 @@ simplify_float_conversion_using_ranges ( 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 @@ -10124,15 +10124,12 @@ simplify_float_conversion_using_ranges ( && 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 Index: gcc/optabs.c =================================================================== --- gcc/optabs.c 2017-07-13 09:18:21.534428932 +0100 +++ gcc/optabs.c 2017-07-13 09:18:22.935277839 +0100 @@ -1185,13 +1185,13 @@ expand_binop (machine_mode mode, optab b 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); @@ -1252,14 +1252,14 @@ expand_binop (machine_mode mode, optab b && 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; @@ -3701,7 +3701,7 @@ can_compare_p (enum rtx_code code, machi && 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); Index: gcc/gdbhooks.py =================================================================== --- gcc/gdbhooks.py 2017-02-23 19:54:12.000000000 +0000 +++ gcc/gdbhooks.py 2017-07-13 09:18:22.928278591 +0100 @@ -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 '' + 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( Index: gcc/ada/gcc-interface/decl.c =================================================================== --- gcc/ada/gcc-interface/decl.c 2017-06-22 12:22:56.063377521 +0100 +++ gcc/ada/gcc-interface/decl.c 2017-07-13 09:18:22.913280204 +0100 @@ -8576,7 +8576,7 @@ validate_size (Uint uint_size, tree gnu_ { 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)); }