From patchwork Thu Mar 21 04:43:18 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Law X-Patchwork-Id: 229553 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 D66F62C00B9 for ; Thu, 21 Mar 2013 15:43:41 +1100 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:subject:content-type; q= dns; s=default; b=Of5Yez/lBZjQ1LJyp3fFh0wpDJFeb2pue6qBieafizgv15 azkVE89QJHbTUiYT5SSSvtmWR1zbgxn8+7BiC3MCHKfd/aPD1eBmOc/Em+9NoO4N xsKdHgNRkHn/R+XbkKrzGaXPOthGohZxD96E5G+/8Uyrf6+CZMRG7PDIOR4Vo= 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 :message-id:date:from:mime-version:to:subject:content-type; s= default; bh=Z3BfinBrDlV/k2B8tL9Qs5R4FGE=; b=lPIdsgE00tzjJU4NnmZ8 SZPjWa7CPpzpVHv0uI/5VSWhQxBLrIEl8RTsKCMNRVAM2jsPrW5p3Sl5jPGe1+x9 tkR2k1vBzMqN00OPQcCTX5lrNn8kGJcWDUN319SyxkVU2YDSQcY5xoA8FuU6Z/Eg Dw7PvtjsVKeW1p4SrlnzBSc= Received: (qmail 18862 invoked by alias); 21 Mar 2013 04:43:35 -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 18849 invoked by uid 89); 21 Mar 2013 04:43:23 -0000 X-Spam-SWARE-Status: No, score=-8.4 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, SPF_HELO_PASS, TW_TM autolearn=ham version=3.3.1 Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Thu, 21 Mar 2013 04:43:20 +0000 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r2L4hJjT023193 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Thu, 21 Mar 2013 00:43:19 -0400 Received: from stumpy.slc.redhat.com (ovpn-113-48.phx2.redhat.com [10.3.113.48]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id r2L4hIBM018123 for ; Thu, 21 Mar 2013 00:43:19 -0400 Message-ID: <514A8FE6.7060704@redhat.com> Date: Wed, 20 Mar 2013 22:43:18 -0600 From: Jeff Law User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130110 Thunderbird/17.0.2 MIME-Version: 1.0 To: gcc-patches Subject: Record missing equivalence This was something I spotted while looking at why certain redundant conditionals were not eliminated. In particular this affects the compiler's ability to eliminate a variety of gimple checking tests. Consider an equality comparison if (a == 10) true arm else else arm We obviously want to record an equivalence so that we can replace uses of "a" in the true arm with "10". Now consider if "a" was set by a widening type conversion. a = (int) z; /* Assume Z is a narrower type */ if (a == 10) true arm else else arm We'd really like to also record an equivalence for "z" in the true arm so that uses of "z" can be replaced with "10". We restrict this to widening conversions where the constant is equal in both the original and widened type. That's precisely what this patch does. When we're going to record an equivalence from an equality comparison between an SSA_NAME and a constant, we look to see if the SSA_NAME was set from widening conversion and verify the constant is the same in both the original and widened type. When true, we record the additional equivalence. As I mentioned, this ultimately allows us to discover more redundant conditionals for gimple checking and eliminate them. The included testcase is drastically simplified and merely tests for whether or not we record & propagate the additional equivalence. It does not show the eliminated tests. Bootstrapped and regression tested on x86_64-unknown-linux-gnu. Installed on the trunk. commit 4c7d3ee54cf7035b247c685a68968d0a60b01601 Author: Jeff Law Date: Wed Mar 20 22:39:13 2013 -0600 * tree-ssa-dom.c (record_equivalences_from_incoming_edge): Record addititional equivalences for equality comparisons between an SSA_NAME and a constant where the SSA_NAME was set from a widening conversion. * g++.dg/tree-ssa/ssa-dom.C: New test. diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5ecdc8f..5f93edd 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2013-03-20 Jeff Law + + * tree-ssa-dom.c (record_equivalences_from_incoming_edge): Record + addititional equivalences for equality comparisons between an SSA_NAME + and a constant where the SSA_NAME was set from a widening conversion. + 2013-03-20 Walter Lee * config/tilegx/sync.md (atomic_test_and_set): New pattern. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 93d02bb..99a366d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2013-03-20 Jeff Law + + * g++.dg/tree-ssa/ssa-dom.C: New test. + + 2013-03-20 Michael Meissner * gcc.target/powerpc/mmfpgpr.c: New test. diff --git a/gcc/testsuite/g++.dg/tree-ssa/ssa-dom.C b/gcc/testsuite/g++.dg/tree-ssa/ssa-dom.C new file mode 100644 index 0000000..5f63865 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/ssa-dom.C @@ -0,0 +1,104 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-dom1" } */ + +typedef long unsigned int size_t; +extern void abort (void) __attribute__ ((__noreturn__)); +union tree_node; +typedef union tree_node *tree; +union gimple_statement_d; +typedef union gimple_statement_d *gimple; +typedef const union gimple_statement_d *const_gimple; + +enum gimple_code +{ + GIMPLE_RETURN = 10, +}; + + + + + +struct gimple_statement_base +{ + + + enum gimple_code code:8; +}; + + +enum gimple_statement_structure_enum +{ + xyz +}; + + + + + + +union gimple_statement_d +{ + struct gimple_statement_base gsbase; +}; + + + + + +extern size_t const gimple_ops_offset_[]; + + +extern enum gimple_statement_structure_enum const gss_for_code_[]; + + +static inline enum gimple_code +gimple_code (const_gimple g) +{ + return g->gsbase.code; +} + + + + +static inline enum gimple_statement_structure_enum +gss_for_code (enum gimple_code code) +{ + return gss_for_code_[code]; +} + + + + +static inline enum gimple_statement_structure_enum +gimple_statement_structure (gimple gs) +{ + return gss_for_code (gimple_code (gs)); +} + + +static inline tree * +gimple_ops (gimple gs) +{ + size_t off; + off = gimple_ops_offset_[gimple_statement_structure (gs)]; + return (tree *) ((char *) gs + off); +} + + +static inline void +gimple_set_op (gimple gs, unsigned i, tree op) +{ + gimple_ops (gs)[i] = op; +} + +void +gimple_return_set_retval (gimple gs, tree retval) +{ + const_gimple __gs = (gs); + if (gimple_code (__gs) != (GIMPLE_RETURN)) + abort (); + gimple_set_op (gs, 0, retval); +} +/* { dg-final { scan-tree-dump-times "gss_for_code_.10." 1 "dom1"} } */ +/* { dg-final { cleanup-tree-dump "dom1" } } */ + diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c index e8b1551..57b814c 100644 --- a/gcc/tree-ssa-dom.c +++ b/gcc/tree-ssa-dom.c @@ -1135,6 +1135,33 @@ record_equivalences_from_incoming_edge (basic_block bb) if (lhs) record_equality (lhs, rhs); + /* If LHS is an SSA_NAME and RHS is a constant and LHS was set + via a widening type conversion, then we may be able to record + additional equivalences. */ + if (lhs + && TREE_CODE (lhs) == SSA_NAME + && is_gimple_constant (rhs)) + { + gimple defstmt = SSA_NAME_DEF_STMT (lhs); + + if (defstmt + && is_gimple_assign (defstmt) + && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (defstmt))) + { + tree old_rhs = gimple_assign_rhs1 (defstmt); + tree newval = fold_convert (TREE_TYPE (old_rhs), rhs); + + /* If this was a widening conversion and if RHS is converted + to the type of OLD_RHS and has the same value, then we + can record an equivalence between OLD_RHS and the + converted representation of RHS. */ + if ((TYPE_PRECISION (TREE_TYPE (lhs)) + > TYPE_PRECISION (TREE_TYPE (old_rhs))) + && operand_equal_p (rhs, newval, 0)) + record_equality (old_rhs, newval); + } + } + for (i = 0; edge_info->cond_equivalences.iterate (i, &eq); ++i) record_cond (eq); }