From patchwork Thu Sep 22 11:10:08 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Biener X-Patchwork-Id: 1362 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:5044:0:0:0:0:0 with SMTP id h4csp136576wrt; Thu, 22 Sep 2022 04:10:57 -0700 (PDT) X-Google-Smtp-Source: AMsMyM6TBhXGGmLYu/GxG8ucxlD+ScUdp7B5XqqixseTeap9lLhcO44THeV4IW3HeeV3UJjXrxqH X-Received: by 2002:a17:906:fe09:b0:73d:90ae:f801 with SMTP id wy9-20020a170906fe0900b0073d90aef801mr2112435ejb.699.1663845057424; Thu, 22 Sep 2022 04:10:57 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1663845057; cv=none; d=google.com; s=arc-20160816; b=Z3pC4NBDrj1yhsAH6WjgrAONgWL4MSFnY+uWmotKhfDRLGtlT+QEDaNuG40oAXBqLZ GaWh1vEqw55/XZ2P9m+1o9b9IIiuEccEG4uEIhH8aQB5KEdRgl4oiPRZ4wHtYj8ppfDI WnFIuZlgj1R4Aoz58XpdnmVdwDZHcURmsKs6ytnUqg0m94xlFZk2oa786w4bF6JLen8C CU5dfl9UkI9sTjBkqIiY3ZO7xw4NbDCjAHiAcHSIpAX3u3zg6NkTUS/RbkkVPi/rjzr5 00R8GC+7pZJ+yTIzqFbO6CQ56fM2ywAIqo1rKI1esPLaMv0bfwQW3Htmdv4a5sLwKVUD 5/4g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:reply-to:from:list-subscribe:list-help:list-post :list-archive:list-unsubscribe:list-id:precedence:message-id :mime-version:subject:to:date:dmarc-filter:delivered-to :dkim-signature:dkim-filter; bh=bNUlFdqo/7+kPEvA3PEBJm4nZWcDSJ6asAC6NTYJmQE=; b=srWV5tUY0hPH2mWMRj9i+FJf9ga9oeKPcUPqbkG/lgOUvw75mcGsoaqUNpTzmFZ9kx IzhK5i8cCboHq7bfCPesyDc8nW9hG5+xD8cr3H9s0fOz0nwDKwfA+GChZzwiv1abvjrO Yv9zwqCrJY5NrNdobZ1EHp/+x6pId0ME/trr2Cj32j3yqJTP5juOmIxMfdcJ3ZKWZdb4 BD9g16bDsgjjDPwpiSPI2sMp0LKoZ+gvFwt78wqCS/UvK0RruA7CThV7J9RzHG+wMRNt OmfMUdV1dCk34Wl0wyiWcmz9lps7OYYcS2Tj7rsEbtFC0t3kpxLiElQgSy9HapMAl6XM mn8g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=V0Bu1dtd; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id y8-20020a1709064b0800b00780e844b2eesi3983450eju.482.2022.09.22.04.10.57 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Sep 2022 04:10:57 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=V0Bu1dtd; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 4AA3D3857BAA for ; Thu, 22 Sep 2022 11:10:54 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4AA3D3857BAA DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1663845054; bh=bNUlFdqo/7+kPEvA3PEBJm4nZWcDSJ6asAC6NTYJmQE=; h=Date:To:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=V0Bu1dtdYAJ/SrDuwKM6kKNPR2dXC0XvUASIVL7OLyv/DK6y7vsG7zyGUijrJ0dRW N5SrdkALJwgtNSRXgnOtIlfXgrBNmmfU2M7pDq+6sqxeBE5uJtx9UvPF2/vPcFWuy3 dkdfECqQCLE7ddNj8IxVuzHO5lML4z3MTJeWcFtw= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from smtp-out2.suse.de (smtp-out2.suse.de [IPv6:2001:67c:2178:6::1d]) by sourceware.org (Postfix) with ESMTPS id 7EE5A3858422 for ; Thu, 22 Sep 2022 11:10:10 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 7EE5A3858422 Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id 51A641F8E7 for ; Thu, 22 Sep 2022 11:10:09 +0000 (UTC) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 3EF0413AA5 for ; Thu, 22 Sep 2022 11:10:09 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id mlD8DZFCLGPhMQAAMHmgww (envelope-from ) for ; Thu, 22 Sep 2022 11:10:09 +0000 Date: Thu, 22 Sep 2022 13:10:08 +0200 (CEST) To: gcc-patches@gcc.gnu.org Subject: [PATCH] tree-optimization/106922 - missed FRE/PRE MIME-Version: 1.0 Message-Id: <20220922111009.3EF0413AA5@imap2.suse-dmz.suse.de> X-Spam-Status: No, score=-11.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Richard Biener via Gcc-patches From: Richard Biener Reply-To: Richard Biener Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1744667994866128712?= X-GMAIL-MSGID: =?utf-8?q?1744667994866128712?= The following enhances the store-with-same-value trick in vn_reference_lookup_3 by not only looking for a = val; *ptr = val; .. = a; but also *ptr = val; other = x; .. = a; where the earlier store is more than one hop away. It does this by queueing the actual value to compare until after the walk but as disadvantage only allows a single such skipped store from a constant value. Unfortunately we cannot handle defs from non-constants this way since we're prone to pick up values from the past loop iteration this way and we have no good way to identify values that are invariant in the currently iterated cycle. That's why we keep the single-hop lookup for those cases. gcc.dg/tree-ssa/pr87126.c would be a testcase that's un-XFAILed when we'd handle those as well. Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed. PR tree-optimization/106922 * tree-ssa-sccvn.cc (vn_walk_cb_data::same_val): New member. (vn_walk_cb_data::finish): Perform delayed verification of a skipped may-alias. (vn_reference_lookup_pieces): Likewise. (vn_reference_lookup): Likewise. (vn_reference_lookup_3): When skipping stores of the same value also handle constant stores that are more than a single VDEF away by delaying the verification. * gcc.dg/tree-ssa/ssa-fre-100.c: New testcase. * g++.dg/tree-ssa/pr106922.C: Adjust. --- gcc/testsuite/g++.dg/tree-ssa/pr106922.C | 3 +- gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-100.c | 25 ++++++ gcc/tree-ssa-sccvn.cc | 97 ++++++++++++++------- 3 files changed, 93 insertions(+), 32 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-100.c diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr106922.C b/gcc/testsuite/g++.dg/tree-ssa/pr106922.C index faf379b0361..14fa061de20 100644 --- a/gcc/testsuite/g++.dg/tree-ssa/pr106922.C +++ b/gcc/testsuite/g++.dg/tree-ssa/pr106922.C @@ -87,5 +87,4 @@ void testfunctionfoo() { } } -// { dg-final { scan-tree-dump-times "Found fully redundant value" 4 "pre" { xfail { ! lp64 } } } } -// { dg-final { scan-tree-dump-not "m_initialized" "cddce3" { xfail { ! lp64 } } } } +// { dg-final { scan-tree-dump-not "m_initialized" "dce3" } } diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-100.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-100.c new file mode 100644 index 00000000000..ead76548f3d --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-100.c @@ -0,0 +1,25 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-fre1" } */ + +float bar, baz; +void foo (int *p, int n) +{ + *p = 0; + do + { + bar = 1.; + /* When iterating we should have optimistically value-numbered + *p to zero, on the second iteration we have to prove the + store below does not affect the value of this load though. + We can compare the stored value against the value from the + previous iteration instead relying on a non-walking lookup. */ + if (*p) + { + baz = 2.; + *p = 0; + } + } + while (--n); +} + +/* { dg-final { scan-tree-dump-not "baz" "fre1" } } */ diff --git a/gcc/tree-ssa-sccvn.cc b/gcc/tree-ssa-sccvn.cc index 85a7698f694..9c12a8e4f03 100644 --- a/gcc/tree-ssa-sccvn.cc +++ b/gcc/tree-ssa-sccvn.cc @@ -1803,7 +1803,8 @@ struct vn_walk_cb_data vn_lookup_kind vn_walk_kind_, bool tbaa_p_, tree mask_, bool redundant_store_removal_p_) : vr (vr_), last_vuse_ptr (last_vuse_ptr_), last_vuse (NULL_TREE), - mask (mask_), masked_result (NULL_TREE), vn_walk_kind (vn_walk_kind_), + mask (mask_), masked_result (NULL_TREE), same_val (NULL_TREE), + vn_walk_kind (vn_walk_kind_), tbaa_p (tbaa_p_), redundant_store_removal_p (redundant_store_removal_p_), saved_operands (vNULL), first_set (-2), first_base_set (-2), known_ranges (NULL) @@ -1864,6 +1865,7 @@ struct vn_walk_cb_data tree last_vuse; tree mask; tree masked_result; + tree same_val; vn_lookup_kind vn_walk_kind; bool tbaa_p; bool redundant_store_removal_p; @@ -1902,6 +1904,8 @@ vn_walk_cb_data::finish (alias_set_type set, alias_set_type base_set, tree val) masked_result = val; return (void *) -1; } + if (same_val && !operand_equal_p (val, same_val)) + return (void *) -1; vec &operands = saved_operands.exists () ? saved_operands : vr->operands; return vn_reference_lookup_or_insert_for_pieces (last_vuse, set, base_set, @@ -2675,36 +2679,57 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *data_, and return the found value. */ if (is_gimple_reg_type (TREE_TYPE (lhs)) && types_compatible_p (TREE_TYPE (lhs), vr->type) - && (ref->ref || data->orig_ref.ref)) - { - tree *saved_last_vuse_ptr = data->last_vuse_ptr; - /* Do not update last_vuse_ptr in vn_reference_lookup_2. */ - data->last_vuse_ptr = NULL; - tree saved_vuse = vr->vuse; - hashval_t saved_hashcode = vr->hashcode; - void *res = vn_reference_lookup_2 (ref, gimple_vuse (def_stmt), data); - /* Need to restore vr->vuse and vr->hashcode. */ - vr->vuse = saved_vuse; - vr->hashcode = saved_hashcode; - data->last_vuse_ptr = saved_last_vuse_ptr; - if (res && res != (void *)-1) + && (ref->ref || data->orig_ref.ref) + && !data->same_val + && !data->mask + && data->partial_defs.is_empty () + && multiple_p (get_object_alignment + (ref->ref ? ref->ref : data->orig_ref.ref), + ref->size) + && multiple_p (get_object_alignment (lhs), ref->size)) + { + tree rhs = gimple_assign_rhs1 (def_stmt); + /* ??? We may not compare to ahead values which might be from + a different loop iteration but only to loop invariants. Use + CONSTANT_CLASS_P (unvalueized!) as conservative approximation. + The one-hop lookup below doesn't have this issue since there's + a virtual PHI before we ever reach a backedge to cross. */ + if (CONSTANT_CLASS_P (rhs)) { - vn_reference_t vnresult = (vn_reference_t) res; - tree rhs = gimple_assign_rhs1 (def_stmt); - if (TREE_CODE (rhs) == SSA_NAME) - rhs = SSA_VAL (rhs); - if (vnresult->result - && operand_equal_p (vnresult->result, rhs, 0) - /* We have to honor our promise about union type punning - and also support arbitrary overlaps with - -fno-strict-aliasing. So simply resort to alignment to - rule out overlaps. Do this check last because it is - quite expensive compared to the hash-lookup above. */ - && multiple_p (get_object_alignment - (ref->ref ? ref->ref : data->orig_ref.ref), - ref->size) - && multiple_p (get_object_alignment (lhs), ref->size)) - return res; + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, + "Skipping possible redundant definition "); + print_gimple_stmt (dump_file, def_stmt, 0); + } + /* Delay the actual compare of the values to the end of the walk + but do not update last_vuse from here. */ + data->last_vuse_ptr = NULL; + data->same_val = rhs; + return NULL; + } + else + { + tree *saved_last_vuse_ptr = data->last_vuse_ptr; + /* Do not update last_vuse_ptr in vn_reference_lookup_2. */ + data->last_vuse_ptr = NULL; + tree saved_vuse = vr->vuse; + hashval_t saved_hashcode = vr->hashcode; + void *res = vn_reference_lookup_2 (ref, gimple_vuse (def_stmt), + data); + /* Need to restore vr->vuse and vr->hashcode. */ + vr->vuse = saved_vuse; + vr->hashcode = saved_hashcode; + data->last_vuse_ptr = saved_last_vuse_ptr; + if (res && res != (void *)-1) + { + vn_reference_t vnresult = (vn_reference_t) res; + if (TREE_CODE (rhs) == SSA_NAME) + rhs = SSA_VAL (rhs); + if (vnresult->result + && operand_equal_p (vnresult->result, rhs, 0)) + return res; + } } } } @@ -3798,6 +3823,14 @@ vn_reference_lookup_pieces (tree vuse, alias_set_type set, if (ops_for_ref != shared_lookup_references) ops_for_ref.release (); gcc_checking_assert (vr1.operands == shared_lookup_references); + if (*vnresult + && data.same_val + && (!(*vnresult)->result + || !operand_equal_p ((*vnresult)->result, data.same_val))) + { + *vnresult = NULL; + return NULL_TREE; + } } if (*vnresult) @@ -3913,6 +3946,10 @@ vn_reference_lookup (tree op, tree vuse, vn_lookup_kind kind, if (wvnresult) { gcc_assert (mask == NULL_TREE); + if (data.same_val + && (!wvnresult->result + || !operand_equal_p (wvnresult->result, data.same_val))) + return NULL_TREE; if (vnresult) *vnresult = wvnresult; return wvnresult->result;