From patchwork Mon Nov 12 13:31:32 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marc Glisse X-Patchwork-Id: 198389 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 263142C008C for ; Tue, 13 Nov 2012 00:31:51 +1100 (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=1353331916; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Date:From:To:Subject:Message-ID:User-Agent:MIME-Version: Content-Type:Mailing-List:Precedence:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:Sender:Delivered-To; bh=XfHAmJj zYBh65umuP92J/C5IE5Q=; b=mXTl267nZ2IWUGifRvJ2ixtouBUMuL4qk7V4gtu sjr60ldrtUd9TtXBCc0RVck2X6U+FOynMG0n35sfp1vQyVsxPtCO4xFsMk4L2nwz 8FKwbE3ii1EcAXKJqwDnJooqCg3J9t2DmI+E3TCXI2EfMJHPatxZuMXGEwc9H2XI MaUE= 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:Date:From:To:Subject:Message-ID:User-Agent:MIME-Version:Content-Type:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=pv9cZPiyeFlwMMfGRHkCcmEp49UwNwIOi6MNCqHWOOvoQBhQ37k9/ssFua2FH3 ecEEwmNlNVybNHhuaVI2uFeKk4QZEe6Jj11Yf5vbBkTAmBKFgXfld+fJ+c4ljugh MHbux9naTJhgHvJIfl07dP+h4NwCZ08fAwsZ/jdrypzRQ=; Received: (qmail 17851 invoked by alias); 12 Nov 2012 13:31:42 -0000 Received: (qmail 17837 invoked by uid 22791); 12 Nov 2012 13:31:41 -0000 X-SWARE-Spam-Status: No, hits=-7.2 required=5.0 tests=AWL, BAYES_00, KHOP_RCVD_UNTRUST, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mail4-relais-sop.national.inria.fr (HELO mail4-relais-sop.national.inria.fr) (192.134.164.105) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 12 Nov 2012 13:31:34 +0000 Received: from stedding.saclay.inria.fr ([193.55.250.194]) by mail4-relais-sop.national.inria.fr with ESMTP/TLS/DHE-RSA-AES128-SHA; 12 Nov 2012 14:31:32 +0100 Received: from glisse (helo=localhost) by stedding.saclay.inria.fr with local-esmtp (Exim 4.80) (envelope-from ) id 1TXu6u-0002J3-6K for gcc-patches@gcc.gnu.org; Mon, 12 Nov 2012 14:31:32 +0100 Date: Mon, 12 Nov 2012 14:31:32 +0100 (CET) From: Marc Glisse To: gcc-patches@gcc.gnu.org Subject: bit_field_ref of constructor of vectors Message-ID: User-Agent: Alpine 2.02 (DEB 1266 2009-07-14) MIME-Version: 1.0 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 Hello, this patch lets us fold a bit_field_ref of a constructor even when the elements are vectors. Writing a testcase is not that convenient because of the lack of a dead code elimination pass after forwprop4 (RTL doesn't always remove everything either), but I see a clear difference on this test on x86_64 without AVX. typedef double vec __attribute__((vector_size(4*sizeof(double)))); void f(vec*x){ *x+=*x+*x; } double g(vec*x){ return (*x+*x)[3]; } void h(vec*x, double a, double b, double c, double d){ vec y={a,b,c,d}; *x+=y; } I don't know if the patch (assuming it is ok) is suitable for stage 3, it may have to wait. It passes bootstrap+testsuite. I am still not quite sure why we even have a valid_gimple_rhs_p function (after which we usually give up if it says no) instead of gimplifying, so I may have missed a reason why CONSTRUCTOR or BIT_FIELD_REF shouldn't be ok. 2012-11-12 Marc Glisse * fold-const.c (fold_ternary_loc) [BIT_FIELD_REF]: Handle CONSTRUCTOR with vector elements. * tree-ssa-propagate.c (valid_gimple_rhs_p): Handle CONSTRUCTOR and BIT_FIELD_REF. Index: gcc/fold-const.c =================================================================== --- gcc/fold-const.c (revision 193429) +++ gcc/fold-const.c (working copy) @@ -14054,65 +14054,75 @@ fold_ternary_loc (location_t loc, enum t unsigned HOST_WIDE_INT n = tree_low_cst (arg1, 1); unsigned HOST_WIDE_INT idx = tree_low_cst (op2, 1); if (n != 0 && (idx % width) == 0 && (n % width) == 0 && ((idx + n) / width) <= TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0))) { idx = idx / width; n = n / width; - if (TREE_CODE (type) == VECTOR_TYPE) + + if (TREE_CODE (arg0) == VECTOR_CST) { - if (TREE_CODE (arg0) == VECTOR_CST) - { - tree *vals = XALLOCAVEC (tree, n); - unsigned i; - for (i = 0; i < n; ++i) - vals[i] = VECTOR_CST_ELT (arg0, idx + i); - return build_vector (type, vals); - } - else - { - VEC(constructor_elt, gc) *vals; - unsigned i; - if (CONSTRUCTOR_NELTS (arg0) == 0) - return build_constructor (type, NULL); - if (TREE_CODE (TREE_TYPE (CONSTRUCTOR_ELT (arg0, - 0)->value)) - != VECTOR_TYPE) - { - vals = VEC_alloc (constructor_elt, gc, n); - for (i = 0; - i < n && idx + i < CONSTRUCTOR_NELTS (arg0); - ++i) - CONSTRUCTOR_APPEND_ELT (vals, NULL_TREE, - CONSTRUCTOR_ELT - (arg0, idx + i)->value); - return build_constructor (type, vals); - } - } + if (n == 1) + return VECTOR_CST_ELT (arg0, idx); + + tree *vals = XALLOCAVEC (tree, n); + for (unsigned i = 0; i < n; ++i) + vals[i] = VECTOR_CST_ELT (arg0, idx + i); + return build_vector (type, vals); + } + + /* Constructor elements can be subvectors. */ + unsigned HOST_WIDE_INT k = 1; + if (CONSTRUCTOR_NELTS (arg0) != 0) + { + tree cons_elem = TREE_TYPE (CONSTRUCTOR_ELT (arg0, 0)->value); + if (TREE_CODE (cons_elem) == VECTOR_TYPE) + k = TYPE_VECTOR_SUBPARTS (cons_elem); } - else if (n == 1) + + /* We keep an exact subset of the constructor elements. */ + if ((idx % k) == 0 && (n % k) == 0) { - if (TREE_CODE (arg0) == VECTOR_CST) - return VECTOR_CST_ELT (arg0, idx); - else if (CONSTRUCTOR_NELTS (arg0) == 0) - return build_zero_cst (type); - else if (TREE_CODE (TREE_TYPE (CONSTRUCTOR_ELT (arg0, - 0)->value)) - != VECTOR_TYPE) + VEC(constructor_elt, gc) *vals; + if (CONSTRUCTOR_NELTS (arg0) == 0) + return build_constructor (type, NULL); + idx /= k; + n /= k; + if (n == 1) { if (idx < CONSTRUCTOR_NELTS (arg0)) return CONSTRUCTOR_ELT (arg0, idx)->value; return build_zero_cst (type); } + vals = VEC_alloc (constructor_elt, gc, n); + for (unsigned i = 0; + i < n && idx + i < CONSTRUCTOR_NELTS (arg0); + ++i) + CONSTRUCTOR_APPEND_ELT (vals, NULL_TREE, + CONSTRUCTOR_ELT + (arg0, idx + i)->value); + return build_constructor (type, vals); + } + /* The bitfield references a single constructor element. */ + else if (idx + n <= (idx / k + 1) * k) + { + if (CONSTRUCTOR_NELTS (arg0) <= idx / k) + return build_zero_cst (type); + else if (n == k) + return CONSTRUCTOR_ELT (arg0, idx / k)->value; + else + return fold_build3_loc (loc, code, type, + CONSTRUCTOR_ELT (arg0, idx / k)->value, op1, + build_int_cst (TREE_TYPE (op2), (idx % k) * width)); } } } /* A bit-field-ref that referenced the full argument can be stripped. */ if (INTEGRAL_TYPE_P (TREE_TYPE (arg0)) && TYPE_PRECISION (TREE_TYPE (arg0)) == tree_low_cst (arg1, 1) && integer_zerop (op2)) return fold_convert_loc (loc, type, arg0); Index: gcc/tree-ssa-propagate.c =================================================================== --- gcc/tree-ssa-propagate.c (revision 193429) +++ gcc/tree-ssa-propagate.c (working copy) @@ -610,24 +610,38 @@ valid_gimple_rhs_p (tree expr) break; } return false; } break; case tcc_vl_exp: return false; case tcc_exceptional: + if (code == CONSTRUCTOR) + { + unsigned i; + tree elt; + FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (expr), i, elt) + if (!is_gimple_val (elt)) + return false; + return true; + } if (code != SSA_NAME) return false; break; + case tcc_reference: + if (code == BIT_FIELD_REF) + return is_gimple_val (TREE_OPERAND (expr, 0)); + return false; + default: return false; } return true; } /* Return true if EXPR is a CALL_EXPR suitable for representation as a single GIMPLE_CALL statement. If the arguments require