From patchwork Wed Aug 1 20:36:01 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 174598 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 29FDC2C007C for ; Thu, 2 Aug 2012 06:36:37 +1000 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1344458198; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Received:From:To:Subject:Date:Message-Id:Mailing-List:Precedence: List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender: Delivered-To; bh=IeSVf1BAaBCakFHnc+NdWeQHWpQ=; b=Y6oJ2RxJaLLUbjd MaGnAwhWIgppIFSonEQaQYLTFreYu2o50xJWCpPboNgNwIQC6+5ZW9Pq7VB+b4Ql 88Ru1ffQcvj2TdiIVOpuTNB/rAazoPIPJAyPBA5Bv56N5iv3H3iDg792AgCtpnUY Q/Fnq0JMahSrJQACwVr9FLxuQTcU= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:Received:Received:From:To:Subject:Date:Message-Id:X-IsSubscribed:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=AckkMI8R1qnvc47ZYgUsD3Z8wG2C0cG7tKIhtHCVpMxYtgKPoHPlIHgxa2ZbjE nLA/vj0zQKumyn1JrrOaTblEpFsvMaZatZFBQyeEKHv1yYUuHQnahrYOIaapdf0o FT79g6ZUJnePpk69xbX2AYiaZJaECsXt0qFjNZCXBxCdM=; Received: (qmail 6532 invoked by alias); 1 Aug 2012 20:36:28 -0000 Received: (qmail 6328 invoked by uid 22791); 1 Aug 2012 20:36:26 -0000 X-SWARE-Spam-Status: No, hits=-4.0 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, KHOP_RCVD_TRUST, RCVD_IN_DNSWL_LOW, RCVD_IN_HOSTKARMA_YE X-Spam-Check-By: sourceware.org Received: from mail-pb0-f47.google.com (HELO mail-pb0-f47.google.com) (209.85.160.47) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 01 Aug 2012 20:36:11 +0000 Received: by pbbrq2 with SMTP id rq2so1587866pbb.20 for ; Wed, 01 Aug 2012 13:36:11 -0700 (PDT) Received: by 10.68.217.100 with SMTP id ox4mr54489194pbc.87.1343853371038; Wed, 01 Aug 2012 13:36:11 -0700 (PDT) Received: from anchor.twiddle.home ([173.160.232.49]) by mx.google.com with ESMTPS id oy8sm3226485pbc.52.2012.08.01.13.36.10 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 01 Aug 2012 13:36:10 -0700 (PDT) From: Richard Henderson To: gcc-patches@gcc.gnu.org Subject: [PATCH 2/2] Allow MODE_PARTIAL_INT in expmed costs Date: Wed, 1 Aug 2012 13:36:01 -0700 Message-Id: <1343853361-21574-2-git-send-email-rth@redhat.com> X-IsSubscribed: yes 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 Testing on m32c reveals that we've been asking for cost of conversion from MODE_PARTIAL_INT. We hadn't actually been initializing those costs, mind. I'm not only allowing the query, but initializing them too. Committed after testing on x86_64 and m32c. r~ * expmed.h (NUM_MODE_PARTIAL_INT): New. (NUM_MODE_VECTOR_INT, NUM_MODE_IP_INT, NUM_MODE_IPV_INT): New. (struct expmed_op_cheap): Size one array on NUM_MODE_IPV_INT. (struct expmed_op_costs): Likewise. (struct target_expmed): Size x_convert_cost on NUM_MODE_IP_INT. (expmed_mode_index): New. (expmed_op_cheap_ptr, expmed_op_cost_ptr): Use expmed_mode_index. (convert_cost_ptr): Likewise. * expmed.c (struct init_expmed_rtl): Rename convert to trunc. (init_expmed_one_conv): Split out from ... (init_expmed_one_mode): ... here. Iterate conversions over partial integer modes too. (init_expmed): Iterate over partial integer modes too. diff --git a/gcc/expmed.c b/gcc/expmed.c index 1fe0034..d91d8f1 100644 --- a/gcc/expmed.c +++ b/gcc/expmed.c @@ -101,7 +101,6 @@ struct init_expmed_rtl struct rtx_def mult; rtunion mult_fld1; struct rtx_def sdiv; rtunion sdiv_fld1; struct rtx_def udiv; rtunion udiv_fld1; - struct rtx_def zext; struct rtx_def sdiv_32; rtunion sdiv_32_fld1; struct rtx_def smod_32; rtunion smod_32_fld1; struct rtx_def wide_mult; rtunion wide_mult_fld1; @@ -112,13 +111,36 @@ struct init_expmed_rtl struct rtx_def shift_add; rtunion shift_add_fld1; struct rtx_def shift_sub0; rtunion shift_sub0_fld1; struct rtx_def shift_sub1; rtunion shift_sub1_fld1; - struct rtx_def convert; + struct rtx_def zext; + struct rtx_def trunc; rtx pow2[MAX_BITS_PER_WORD]; rtx cint[MAX_BITS_PER_WORD]; }; static void +init_expmed_one_conv (struct init_expmed_rtl *all, enum machine_mode to_mode, + enum machine_mode from_mode, bool speed) +{ + int to_size, from_size; + rtx which; + + /* We're given no information about the true size of a partial integer, + only the size of the "full" integer it requires for storage. For + comparison purposes here, reduce the bit size by one in that case. */ + to_size = (GET_MODE_BITSIZE (to_mode) + - (GET_MODE_CLASS (to_mode) == MODE_PARTIAL_INT)); + from_size = (GET_MODE_BITSIZE (from_mode) + - (GET_MODE_CLASS (from_mode) == MODE_PARTIAL_INT)); + + /* Assume cost of zero-extend and sign-extend is the same. */ + which = (to_size < from_size ? &all->trunc : &all->zext); + + PUT_MODE (&all->reg, from_mode); + set_convert_cost (to_mode, from_mode, speed, set_src_cost (which, speed)); +} + +static void init_expmed_one_mode (struct init_expmed_rtl *all, enum machine_mode mode, int speed) { @@ -141,7 +163,8 @@ init_expmed_one_mode (struct init_expmed_rtl *all, PUT_MODE (&all->shift_add, mode); PUT_MODE (&all->shift_sub0, mode); PUT_MODE (&all->shift_sub1, mode); - PUT_MODE (&all->convert, mode); + PUT_MODE (&all->zext, mode); + PUT_MODE (&all->trunc, mode); set_add_cost (speed, mode, set_src_cost (&all->plus, speed)); set_neg_cost (speed, mode, set_src_cost (&all->neg, speed)); @@ -176,8 +199,13 @@ init_expmed_one_mode (struct init_expmed_rtl *all, if (SCALAR_INT_MODE_P (mode)) { - enum machine_mode wider_mode = GET_MODE_WIDER_MODE (mode); - + for (mode_from = MIN_MODE_INT; mode_from <= MAX_MODE_INT; + mode_from = (enum machine_mode)(mode_from + 1)) + init_expmed_one_conv (all, mode, mode_from, speed); + } + if (GET_MODE_CLASS (mode) == MODE_INT) + { + enum machine_mode wider_mode = GET_MODE_WIDER_MODE (mode); if (wider_mode != VOIDmode) { PUT_MODE (&all->zext, wider_mode); @@ -185,33 +213,11 @@ init_expmed_one_mode (struct init_expmed_rtl *all, PUT_MODE (&all->wide_lshr, wider_mode); XEXP (&all->wide_lshr, 1) = GEN_INT (mode_bitsize); - set_mul_widen_cost (speed, wider_mode, set_src_cost (&all->wide_mult, speed)); - set_mul_highpart_cost (speed, mode, set_src_cost (&all->wide_trunc, speed)); + set_mul_widen_cost (speed, wider_mode, + set_src_cost (&all->wide_mult, speed)); + set_mul_highpart_cost (speed, mode, + set_src_cost (&all->wide_trunc, speed)); } - - for (mode_from = GET_CLASS_NARROWEST_MODE (MODE_INT); - mode_from != VOIDmode; - mode_from = GET_MODE_WIDER_MODE (mode_from)) - if (mode != mode_from) - { - unsigned short size_to = GET_MODE_SIZE (mode); - unsigned short size_from = GET_MODE_SIZE (mode_from); - if (size_to < size_from) - { - PUT_CODE (&all->convert, TRUNCATE); - PUT_MODE (&all->reg, mode_from); - set_convert_cost (mode, mode_from, speed, - set_src_cost (&all->convert, speed)); - } - else if (size_from < size_to) - { - /* Assume cost of zero-extend and sign-extend is the same. */ - PUT_CODE (&all->convert, ZERO_EXTEND); - PUT_MODE (&all->reg, mode_from); - set_convert_cost (mode, mode_from, speed, - set_src_cost (&all->convert, speed)); - } - } } } @@ -291,23 +297,27 @@ init_expmed (void) XEXP (&all.shift_sub1, 0) = &all.reg; XEXP (&all.shift_sub1, 1) = &all.shift_mult; - PUT_CODE (&all.convert, TRUNCATE); - XEXP (&all.convert, 0) = &all.reg; + PUT_CODE (&all.trunc, TRUNCATE); + XEXP (&all.trunc, 0) = &all.reg; for (speed = 0; speed < 2; speed++) { crtl->maybe_hot_insn_p = speed; set_zero_cost (speed, set_src_cost (const0_rtx, speed)); - for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT); - mode != VOIDmode; - mode = GET_MODE_WIDER_MODE (mode)) + for (mode = MIN_MODE_INT; mode <= MAX_MODE_INT; + mode = (enum machine_mode)(mode + 1)) init_expmed_one_mode (&all, mode, speed); - for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_INT); - mode != VOIDmode; - mode = GET_MODE_WIDER_MODE (mode)) - init_expmed_one_mode (&all, mode, speed); + if (MIN_MODE_PARTIAL_INT != VOIDmode) + for (mode = MIN_MODE_PARTIAL_INT; mode <= MAX_MODE_PARTIAL_INT; + mode = (enum machine_mode)(mode + 1)) + init_expmed_one_mode (&all, mode, speed); + + if (MIN_MODE_VECTOR_INT != VOIDmode) + for (mode = MIN_MODE_VECTOR_INT; mode <= MAX_MODE_VECTOR_INT; + mode = (enum machine_mode)(mode + 1)) + init_expmed_one_mode (&all, mode, speed); } if (alg_hash_used_p ()) diff --git a/gcc/expmed.h b/gcc/expmed.h index bde5cae..05d0c15 100644 --- a/gcc/expmed.h +++ b/gcc/expmed.h @@ -124,23 +124,24 @@ struct alg_hash_entry { #define NUM_ALG_HASH_ENTRIES 307 #endif -#define NUM_MODE_INT (MAX_MODE_INT - MIN_MODE_INT + 1) -#define NUM_MODE_VECTOR_INT (MAX_MODE_VECTOR_INT - MIN_MODE_VECTOR_INT + 1) +#define NUM_MODE_INT \ + (MAX_MODE_INT - MIN_MODE_INT + 1) +#define NUM_MODE_PARTIAL_INT \ + (MIN_MODE_PARTIAL_INT == VOIDmode ? 0 \ + : MAX_MODE_PARTIAL_INT - MIN_MODE_PARTIAL_INT + 1) +#define NUM_MODE_VECTOR_INT \ + (MIN_MODE_VECTOR_INT == VOIDmode ? 0 \ + : MAX_MODE_VECTOR_INT - MIN_MODE_VECTOR_INT + 1) + +#define NUM_MODE_IP_INT (NUM_MODE_INT + NUM_MODE_PARTIAL_INT) +#define NUM_MODE_IPV_INT (NUM_MODE_IP_INT + NUM_MODE_VECTOR_INT) struct expmed_op_cheap { - /* Whether an operation is cheap in a given integer mode. */ - bool cheap_int[2][NUM_MODE_INT]; - - /* Whether an operation is cheap in a given vector integer mode. */ - bool cheap_vector_int[2][NUM_MODE_VECTOR_INT]; + bool cheap[2][NUM_MODE_IPV_INT]; }; struct expmed_op_costs { - /* The cost of an operation in a given integer mode. */ - int int_cost[2][NUM_MODE_INT]; - - /* The cost of an operation in a given vector integer mode. */ - int vector_int_cost[2][NUM_MODE_VECTOR_INT]; + int cost[2][NUM_MODE_IPV_INT]; }; /* Target-dependent globals. */ @@ -178,7 +179,7 @@ struct target_expmed { /* Conversion costs are only defined between two scalar integer modes of different sizes. The first machine mode is the destination mode, and the second is the source mode. */ - int x_convert_cost[2][NUM_MODE_INT][NUM_MODE_INT]; + int x_convert_cost[2][NUM_MODE_IP_INT][NUM_MODE_IP_INT]; }; extern struct target_expmed default_target_expmed; @@ -212,6 +213,24 @@ set_alg_hash_used_p (bool usedp) this_target_expmed->x_alg_hash_used_p = usedp; } +/* Compute an index into the cost arrays by mode class. */ + +static inline int +expmed_mode_index (enum machine_mode mode) +{ + switch (GET_MODE_CLASS (mode)) + { + case MODE_INT: + return mode - MIN_MODE_INT; + case MODE_PARTIAL_INT: + return mode - MIN_MODE_PARTIAL_INT + NUM_MODE_INT; + case MODE_VECTOR_INT: + return mode - MIN_MODE_VECTOR_INT + NUM_MODE_IP_INT; + default: + gcc_unreachable (); + } +} + /* Return a pointer to a boolean contained in EOC indicating whether a particular operation performed in MODE is cheap when optimizing for SPEED. */ @@ -220,19 +239,8 @@ static inline bool * expmed_op_cheap_ptr (struct expmed_op_cheap *eoc, bool speed, enum machine_mode mode) { - gcc_assert (GET_MODE_CLASS (mode) == MODE_INT - || GET_MODE_CLASS (mode) == MODE_VECTOR_INT); - - if (GET_MODE_CLASS (mode) == MODE_INT) - { - int idx = mode - MIN_MODE_INT; - return &eoc->cheap_int[speed][idx]; - } - else - { - int idx = mode - MIN_MODE_VECTOR_INT; - return &eoc->cheap_vector_int[speed][idx]; - } + int idx = expmed_mode_index (mode); + return &eoc->cheap[speed][idx]; } /* Return a pointer to a cost contained in COSTS when a particular @@ -242,19 +250,8 @@ static inline int * expmed_op_cost_ptr (struct expmed_op_costs *costs, bool speed, enum machine_mode mode) { - gcc_assert (GET_MODE_CLASS (mode) == MODE_INT - || GET_MODE_CLASS (mode) == MODE_VECTOR_INT); - - if (GET_MODE_CLASS (mode) == MODE_INT) - { - int idx = mode - MIN_MODE_INT; - return &costs->int_cost[speed][idx]; - } - else - { - int idx = mode - MIN_MODE_VECTOR_INT; - return &costs->vector_int_cost[speed][idx]; - } + int idx = expmed_mode_index (mode); + return &costs->cost[speed][idx]; } /* Subroutine of {set_,}sdiv_pow2_cheap. Not to be used otherwise. */ @@ -631,15 +628,12 @@ static inline int * convert_cost_ptr (enum machine_mode to_mode, enum machine_mode from_mode, bool speed) { - int to_idx, from_idx; + int to_idx = expmed_mode_index (to_mode); + int from_idx = expmed_mode_index (from_mode); - gcc_assert (to_mode >= MIN_MODE_INT - && to_mode <= MAX_MODE_INT - && from_mode >= MIN_MODE_INT - && from_mode <= MAX_MODE_INT); + gcc_assert (IN_RANGE (to_idx, 0, NUM_MODE_IP_INT - 1)); + gcc_assert (IN_RANGE (from_idx, 0, NUM_MODE_IP_INT - 1)); - to_idx = to_mode - MIN_MODE_INT; - from_idx = from_mode - MIN_MODE_INT; return &this_target_expmed->x_convert_cost[speed][to_idx][from_idx]; }