From patchwork Wed Jun 12 20:17:38 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marc Glisse X-Patchwork-Id: 250872 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]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "localhost", Issuer "www.qmailtoaster.com" (not verified)) by ozlabs.org (Postfix) with ESMTPS id 2B3D12C009E for ; Thu, 13 Jun 2013 06:17:54 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:in-reply-to:message-id:references :mime-version:content-type; q=dns; s=default; b=J3whVCeEfHQN/jIT 63kBC+2DPMxdi0f8eJpA1EXEqEcNxBL8KpAwVi9UWbZ3s0c42Xjvb+7Nzm862v00 5CXmuLqjkWguECVNNJeoJd3MBzO1N53WiGmgzt84SOI3MJaoJ3XlZULHo3fD08Kc fUnJoukh4j9CXg7NMyqP5kveH4c= 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:date :from:to:cc:subject:in-reply-to:message-id:references :mime-version:content-type; s=default; bh=oNgM08Eo0GBn52ZdGpV+Y1 znsH4=; b=k65VG0Igh3YgFQpwt9rzwey+uQVxAG9+JtG3IRsGj/77Eqpb2yyxHJ VVgxlGicTVNcooE3lHFHvJwlKLj8Ca8EN7NT0KpYNgVIP1R5LmJo3JUhPSkAx5Hh cLFJPMLhs3aOO+K+LjaMwfLVoTUWHaKoVOD1L+HEG/WXzEIfFfjb0= Received: (qmail 13551 invoked by alias); 12 Jun 2013 20:17:48 -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 13525 invoked by uid 89); 12 Jun 2013 20:17:43 -0000 X-Spam-SWARE-Status: No, score=-5.4 required=5.0 tests=AWL, BAYES_00, KHOP_THREADED, RP_MATCHES_RCVD, TW_TM autolearn=ham version=3.3.1 Received: from mail2-relais-roc.national.inria.fr (HELO mail2-relais-roc.national.inria.fr) (192.134.164.83) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Wed, 12 Jun 2013 20:17:41 +0000 Received: from stedding.saclay.inria.fr ([193.55.250.194]) by mail2-relais-roc.national.inria.fr with ESMTP/TLS/DHE-RSA-AES128-SHA; 12 Jun 2013 22:17:38 +0200 Received: from glisse (helo=localhost) by stedding.saclay.inria.fr with local-esmtp (Exim 4.80) (envelope-from ) id 1UmrUA-0007Zn-Kr; Wed, 12 Jun 2013 22:17:38 +0200 Date: Wed, 12 Jun 2013 22:17:38 +0200 (CEST) From: Marc Glisse To: Richard Biener cc: Jeff Law , gcc-patches@gcc.gnu.org Subject: Re: More forwprop for vectors In-Reply-To: Message-ID: References: <51B7721C.6050406@redhat.com> User-Agent: Alpine 2.02 (DEB 1266 2009-07-14) MIME-Version: 1.0 X-Virus-Found: No On Wed, 12 Jun 2013, Marc Glisse wrote: >> I suppose it's explicitely not allowing complex integer constants? > > Hmm... Thanks, I keep forgetting complex :-( And complex is even more of a pain than vector to handle. > Testing for CONSTANT_CLASS_P seems sufficient here. Some transformations also > seem valid for complex, and the others are already restricted by the fact > that they involve operators like AND or XOR, or because we exit early for > FLOAT_TYPE_P and FIXED_POINT_TYPE_P. I'll test that (no new macro for now > then). Here is a new version. I added a build_all_ones_cst helper which currently only handles integer-like (complex, vector) types. Bootstrap+testsuite on x86_64-unknown-linux-gnu as usual. 2013-06-13 Marc Glisse * tree-ssa-forwprop.c (simplify_bitwise_binary, associate_plusminus): Generalize to complex and vector. * tree.c (build_all_ones_cst): New function. * tree.h (build_all_ones_cst): Declare it. Index: tree-ssa-forwprop.c =================================================================== --- tree-ssa-forwprop.c (revision 200005) +++ tree-ssa-forwprop.c (working copy) @@ -1971,22 +1971,22 @@ simplify_bitwise_binary (gimple_stmt_ite gimple_assign_set_rhs2 (stmt, b); gimple_assign_set_rhs_code (stmt, def1_code); update_stmt (stmt); return true; } } /* (a | CST1) & CST2 -> (a & CST2) | (CST1 & CST2). */ if (code == BIT_AND_EXPR && def1_code == BIT_IOR_EXPR - && TREE_CODE (arg2) == INTEGER_CST - && TREE_CODE (def1_arg2) == INTEGER_CST) + && CONSTANT_CLASS_P (arg2) + && CONSTANT_CLASS_P (def1_arg2)) { tree cst = fold_build2 (BIT_AND_EXPR, TREE_TYPE (arg2), arg2, def1_arg2); tree tem; gimple newop; if (integer_zerop (cst)) { gimple_assign_set_rhs1 (stmt, def1_arg1); update_stmt (stmt); return true; @@ -2002,34 +2002,33 @@ simplify_bitwise_binary (gimple_stmt_ite gimple_assign_set_rhs_code (stmt, BIT_IOR_EXPR); update_stmt (stmt); return true; } /* Combine successive equal operations with constants. */ if ((code == BIT_AND_EXPR || code == BIT_IOR_EXPR || code == BIT_XOR_EXPR) && def1_code == code - && TREE_CODE (arg2) == INTEGER_CST - && TREE_CODE (def1_arg2) == INTEGER_CST) + && CONSTANT_CLASS_P (arg2) + && CONSTANT_CLASS_P (def1_arg2)) { tree cst = fold_build2 (code, TREE_TYPE (arg2), arg2, def1_arg2); gimple_assign_set_rhs1 (stmt, def1_arg1); gimple_assign_set_rhs2 (stmt, cst); update_stmt (stmt); return true; } /* Canonicalize X ^ ~0 to ~X. */ if (code == BIT_XOR_EXPR - && TREE_CODE (arg2) == INTEGER_CST && integer_all_onesp (arg2)) { gimple_assign_set_rhs_with_ops (gsi, BIT_NOT_EXPR, arg1, NULL_TREE); gcc_assert (gsi_stmt (*gsi) == stmt); update_stmt (stmt); return true; } /* Try simple folding for X op !X, and X op X. */ res = simplify_bitwise_binary_1 (code, TREE_TYPE (arg1), arg1, arg2); @@ -2472,73 +2471,74 @@ associate_plusminus (gimple_stmt_iterato && code != def_code) { /* (A +- B) -+ B -> A. */ code = TREE_CODE (def_rhs1); rhs1 = def_rhs1; rhs2 = NULL_TREE; gimple_assign_set_rhs_with_ops (gsi, code, rhs1, NULL_TREE); gcc_assert (gsi_stmt (*gsi) == stmt); gimple_set_modified (stmt, true); } - else if (TREE_CODE (rhs2) == INTEGER_CST - && TREE_CODE (def_rhs1) == INTEGER_CST) + else if (CONSTANT_CLASS_P (rhs2) + && CONSTANT_CLASS_P (def_rhs1)) { /* (CST +- A) +- CST -> CST +- A. */ tree cst = fold_binary (code, TREE_TYPE (rhs1), def_rhs1, rhs2); if (cst && !TREE_OVERFLOW (cst)) { code = def_code; gimple_assign_set_rhs_code (stmt, code); rhs1 = cst; gimple_assign_set_rhs1 (stmt, rhs1); rhs2 = def_rhs2; gimple_assign_set_rhs2 (stmt, rhs2); gimple_set_modified (stmt, true); } } - else if (TREE_CODE (rhs2) == INTEGER_CST - && TREE_CODE (def_rhs2) == INTEGER_CST + else if (CONSTANT_CLASS_P (rhs2) + && CONSTANT_CLASS_P (def_rhs2) && def_code == PLUS_EXPR) { /* (A + CST) +- CST -> A + CST. */ tree cst = fold_binary (code, TREE_TYPE (rhs1), def_rhs2, rhs2); if (cst && !TREE_OVERFLOW (cst)) { code = PLUS_EXPR; gimple_assign_set_rhs_code (stmt, code); rhs1 = def_rhs1; gimple_assign_set_rhs1 (stmt, rhs1); rhs2 = cst; gimple_assign_set_rhs2 (stmt, rhs2); gimple_set_modified (stmt, true); } } } - else if (def_code == BIT_NOT_EXPR - && INTEGRAL_TYPE_P (TREE_TYPE (rhs1))) + else if (def_code == BIT_NOT_EXPR && code == PLUS_EXPR) { tree def_rhs1 = gimple_assign_rhs1 (def_stmt); - if (code == PLUS_EXPR - && operand_equal_p (def_rhs1, rhs2, 0)) + if (operand_equal_p (def_rhs1, rhs2, 0)) { /* ~A + A -> -1. */ - code = INTEGER_CST; - rhs1 = build_int_cst_type (TREE_TYPE (rhs2), -1); + rhs1 = build_all_ones_cst (TREE_TYPE (rhs2)); rhs2 = NULL_TREE; + code = TREE_CODE (rhs1); gimple_assign_set_rhs_with_ops (gsi, code, rhs1, NULL_TREE); gcc_assert (gsi_stmt (*gsi) == stmt); gimple_set_modified (stmt, true); } - else if (code == PLUS_EXPR - && integer_onep (rhs1)) + else if ((TREE_CODE (TREE_TYPE (rhs1)) != COMPLEX_TYPE + && integer_onep (rhs1)) + || (TREE_CODE (rhs1) == COMPLEX_CST + && integer_onep (TREE_REALPART (rhs1)) + && integer_onep (TREE_IMAGPART (rhs1)))) { /* ~A + 1 -> -A. */ code = NEGATE_EXPR; rhs1 = def_rhs1; rhs2 = NULL_TREE; gimple_assign_set_rhs_with_ops (gsi, code, rhs1, NULL_TREE); gcc_assert (gsi_stmt (*gsi) == stmt); gimple_set_modified (stmt, true); } } @@ -2573,66 +2573,65 @@ associate_plusminus (gimple_stmt_iterato { /* A +- (B +- A) -> +- B. */ code = ((code == PLUS_EXPR) ? TREE_CODE (def_rhs1) : NEGATE_EXPR); rhs1 = def_rhs1; rhs2 = NULL_TREE; gimple_assign_set_rhs_with_ops (gsi, code, rhs1, NULL_TREE); gcc_assert (gsi_stmt (*gsi) == stmt); gimple_set_modified (stmt, true); } - else if (TREE_CODE (rhs1) == INTEGER_CST - && TREE_CODE (def_rhs1) == INTEGER_CST) + else if (CONSTANT_CLASS_P (rhs1) + && CONSTANT_CLASS_P (def_rhs1)) { /* CST +- (CST +- A) -> CST +- A. */ tree cst = fold_binary (code, TREE_TYPE (rhs2), rhs1, def_rhs1); if (cst && !TREE_OVERFLOW (cst)) { code = (code == def_code ? PLUS_EXPR : MINUS_EXPR); gimple_assign_set_rhs_code (stmt, code); rhs1 = cst; gimple_assign_set_rhs1 (stmt, rhs1); rhs2 = def_rhs2; gimple_assign_set_rhs2 (stmt, rhs2); gimple_set_modified (stmt, true); } } - else if (TREE_CODE (rhs1) == INTEGER_CST - && TREE_CODE (def_rhs2) == INTEGER_CST) + else if (CONSTANT_CLASS_P (rhs1) + && CONSTANT_CLASS_P (def_rhs2)) { /* CST +- (A +- CST) -> CST +- A. */ tree cst = fold_binary (def_code == code ? PLUS_EXPR : MINUS_EXPR, TREE_TYPE (rhs2), rhs1, def_rhs2); if (cst && !TREE_OVERFLOW (cst)) { rhs1 = cst; gimple_assign_set_rhs1 (stmt, rhs1); rhs2 = def_rhs1; gimple_assign_set_rhs2 (stmt, rhs2); gimple_set_modified (stmt, true); } } } - else if (def_code == BIT_NOT_EXPR - && INTEGRAL_TYPE_P (TREE_TYPE (rhs2))) + else if (def_code == BIT_NOT_EXPR) { tree def_rhs1 = gimple_assign_rhs1 (def_stmt); if (code == PLUS_EXPR && operand_equal_p (def_rhs1, rhs1, 0)) { /* A + ~A -> -1. */ - code = INTEGER_CST; - rhs1 = build_int_cst_type (TREE_TYPE (rhs1), -1); + rhs1 = build_all_ones_cst (TREE_TYPE (rhs1)); rhs2 = NULL_TREE; + code = TREE_CODE (rhs1); gimple_assign_set_rhs_with_ops (gsi, code, rhs1, NULL_TREE); gcc_assert (gsi_stmt (*gsi) == stmt); gimple_set_modified (stmt, true); } } } } out: if (gimple_modified_p (stmt)) Index: tree.c =================================================================== --- tree.c (revision 200005) +++ tree.c (working copy) @@ -1636,20 +1636,35 @@ build_one_cst (tree type) case COMPLEX_TYPE: return build_complex (type, build_one_cst (TREE_TYPE (type)), build_zero_cst (TREE_TYPE (type))); default: gcc_unreachable (); } } +/* Return an integer of type TYPE containing all 1's in as much precision as + it contains, or a complex or vector whose subparts are such integers. */ + +tree +build_all_ones_cst (tree type) +{ + if (TREE_CODE (type) == COMPLEX_TYPE) + { + tree scalar = build_all_ones_cst (TREE_TYPE (type)); + return build_complex (type, scalar, scalar); + } + else + return build_minus_one_cst (type); +} + /* Return a constant of arithmetic type TYPE which is the opposite of the multiplicative identity of the set TYPE. */ tree build_minus_one_cst (tree type) { switch (TREE_CODE (type)) { case INTEGER_TYPE: case ENUMERAL_TYPE: case BOOLEAN_TYPE: case POINTER_TYPE: case REFERENCE_TYPE: Index: tree.h =================================================================== --- tree.h (revision 200005) +++ tree.h (working copy) @@ -4761,20 +4761,21 @@ extern tree build_vector_stat (tree, tre extern tree build_vector_from_ctor (tree, vec *); extern tree build_vector_from_val (tree, tree); extern tree build_constructor (tree, vec *); extern tree build_constructor_single (tree, tree, tree); extern tree build_constructor_from_list (tree, tree); extern tree build_constructor_va (tree, int, ...); extern tree build_real_from_int_cst (tree, const_tree); extern tree build_complex (tree, tree, tree); extern tree build_one_cst (tree); extern tree build_minus_one_cst (tree); +extern tree build_all_ones_cst (tree); extern tree build_zero_cst (tree); extern tree build_string (int, const char *); extern tree build_tree_list_stat (tree, tree MEM_STAT_DECL); #define build_tree_list(t,q) build_tree_list_stat(t,q MEM_STAT_INFO) extern tree build_tree_list_vec_stat (const vec *MEM_STAT_DECL); #define build_tree_list_vec(v) build_tree_list_vec_stat (v MEM_STAT_INFO) extern tree build_decl_stat (location_t, enum tree_code, tree, tree MEM_STAT_DECL); extern tree build_fn_decl (const char *, tree); #define build_decl(l,c,t,q) build_decl_stat (l,c,t,q MEM_STAT_INFO)